{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!unzip -d  ./work ./work/update0815.zip "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "!pip install -q ipywidgets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "831"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\r\n",
    "import re, glob, os\r\n",
    "import numpy as np\r\n",
    "import copy\r\n",
    "import datetime\r\n",
    "import joblib\r\n",
    "from itertools import product,combinations_with_replacement\r\n",
    "from lightgbm import plot_importance\r\n",
    "%matplotlib inline\r\n",
    "import matplotlib.pyplot as plt\r\n",
    "import lightgbm as lgb\r\n",
    "import numpy as np\r\n",
    "# from pandas.tseries.offsets import MonthEnd, MonthBegin\r\n",
    "from sklearn.model_selection import train_test_split\r\n",
    "from tqdm import tqdm, tqdm_notebook\r\n",
    "\r\n",
    "from sklearn.metrics import mean_squared_error, accuracy_score, confusion_matrix\r\n",
    "from sklearn.model_selection import KFold\r\n",
    "\r\n",
    "\r\n",
    "xls_path = './work/update0815/'\r\n",
    "pkl_path = './work/data_pkl/'\r\n",
    "xls_files = sorted(glob.glob(os.path.join(xls_path, '**/*.xls'),recursive=True))\r\n",
    "len(xls_files)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(29508, 14) (27315, 14)\n",
      "(42507, 13) (14169, 13)\n",
      "(7378, 3) (7378, 3)\n",
      "(14, 3) (14, 3)\n"
     ]
    }
   ],
   "source": [
    "def cls_result(r):\n",
    "        t = -1\n",
    "        if len(r.split(':')) == 2:\n",
    "            left, right = map(int, r.split(':'))\n",
    "            if left > right:\n",
    "                t = 2 # 主场胜\n",
    "            elif left == right:\n",
    "                t = 1 # 主场平\n",
    "            else:\n",
    "                t = 0 # 主场负\n",
    "        return t\n",
    "\n",
    "\n",
    "def read_data_result(path):\n",
    "    columns = ['gid','game_01','game_02','game_03','game_04','game_05','game_06',\\\n",
    "               'game_07','game_08','game_09','game_10','game_11','game_12',\\\n",
    "               'game_13','game_14','hot','sales_14','first_price_14',\\\n",
    "               'second_prize_14','sales_9','first_price_9','open_time']\n",
    "    data = pd.read_excel(path, header=None)\n",
    "    data.columns = columns\n",
    "    data['gid'] = data['gid'].map(str)\n",
    "    return data.loc[:,['gid','first_price_9']]\n",
    "\n",
    "def read_data(path, year):\n",
    "\n",
    "    cols = ['number','match_type','match_rounds','match_time','home','result',\\\n",
    "            'visiting','odds_init_win','odds_init_draw','odds_init_lose']\n",
    "    rename_cols = {'odds_init_win':'odds_final_win',\n",
    "                   'odds_init_draw':'odds_final_draw',\n",
    "                   'odds_init_lose':'odds_final_lose'}\n",
    "\n",
    "    data = pd.read_excel(path, header=[0,1])\n",
    "    data = data.iloc[:,:10]\n",
    "    data.columns = cols\n",
    "    data = data.fillna(method='ffill')\n",
    "    \n",
    "    data = pd.concat([data[data.index % 2 == 0].reset_index(drop=True), \n",
    "                      data[data.index % 2 == 1].iloc[:,-3:].rename(columns=rename_cols).reset_index(drop=True)],axis = 1)\n",
    "    data['result_type'] = data['result'].map(cls_result)\n",
    "    data['result_pay'] = data.apply(find_odds, axis=1)\n",
    "    # data['gid'] = gid\n",
    "    data['home'] = data['home'].str.replace(' ','')\n",
    "    data['visiting'] = data['visiting'].str.replace(' ','')\n",
    "    data['match_time'] = pd.to_datetime(data['match_time'].map(lambda x: '%s-'%year+ x))\n",
    "    del data['number']\n",
    "    return data\n",
    "\n",
    "def read_data_asia(path, year):\n",
    "    d = pd.read_excel(xfile, header=[0,1])\n",
    "    d.iloc[:,:7] = d.iloc[:,:7].fillna(method='ffill')\n",
    "    # d = d.fillna(-1)\n",
    "    cols = ['number','match_type','match_rounds','match_time','home','result',\\\n",
    "            'visiting','macao','ladbrokes','bet365','hg','ysb']\n",
    "    d.columns = cols\n",
    "    d['home'] = d['home'].str.replace(' ','')\n",
    "    d['visiting'] = d['visiting'].str.replace(' ','')\n",
    "    d['result_type'] = d['result'].map(cls_result)\n",
    "    # d['result_pay'] = d.apply(find_odds,axis=1)\n",
    "    d['match_time'] = pd.to_datetime(d['match_time'].map(lambda x: '%s-'%year+ x))\n",
    "    return d\n",
    "\n",
    "def find_odds(x):\n",
    "    if x['result_type'] == 2:\n",
    "        return x['odds_final_win']\n",
    "    elif x['result_type'] == 1:\n",
    "        return x['odds_final_draw']\n",
    "    elif x['result_type'] == 0:\n",
    "        return x['odds_final_lose']\n",
    "    else:\n",
    "        return -1\n",
    "\n",
    "euro_data, asia_data, zcsf_data, future_data = [], [], [], []\n",
    "for xfile in xls_files:\n",
    "    if '竞彩足球' in xfile:\n",
    "        gid = re.search(r\"(\\d{4}-\\d{2}-\\d{2})\",xfile)[0]\n",
    "        year = gid[:4]\n",
    "    elif '足球单场' in xfile:\n",
    "        year = '20'+re.search('\\d{5}',xfile)[0][:2]\n",
    "    elif '足彩胜负' in xfile:\n",
    "        gid = re.search('\\d{5}',xfile)[0]\n",
    "        year = '20'+ gid[:2]\n",
    "    if '亚洲盘口' in xfile:\n",
    "        d = read_data_asia(xfile, year)\n",
    "        asia_data.append(d)\n",
    "    elif '欧洲指数' in xfile:\n",
    "        d = read_data(xfile, year)\n",
    "        if ('足彩胜负' in xfile) and ('足球预测' not in xfile):\n",
    "            d_cp = d.loc[:,['match_time','home']].copy()\n",
    "            d_cp['gid'] = gid\n",
    "            zcsf_data.append(d_cp)\n",
    "        if '足球预测' in xfile:\n",
    "            d_cp = d.loc[:,['match_time','home']].copy()\n",
    "            d_cp['gid'] = gid\n",
    "            future_data.append(d_cp)\n",
    "        euro_data.append(d)\n",
    "\n",
    "        \n",
    "euro_data = pd.concat(euro_data, axis=0) # .drop_duplicates()\n",
    "asia_data = pd.concat(asia_data, axis=0)\n",
    "zcsf_data = pd.concat(zcsf_data, axis=0)\n",
    "future_data = pd.concat(future_data, axis=0)\n",
    "\n",
    "# data.head().T\n",
    "\n",
    "# euro_data = euro_data[euro_data.result_type != -1]\n",
    "# zcsf_data = zcsf_data[zcsf_data.result_type != -1]\n",
    "\n",
    "print(euro_data.shape, euro_data.drop_duplicates(subset=['match_time', 'home']).shape)\n",
    "print(asia_data.shape, asia_data.drop_duplicates(subset=['match_time', 'home']).shape)\n",
    "print(zcsf_data.shape, zcsf_data.drop_duplicates(subset=['match_time', 'home']).shape)\n",
    "print(future_data.shape, future_data.drop_duplicates(subset=['match_time', 'home']).shape)\n",
    "\n",
    "\n",
    "euro_data = euro_data.drop_duplicates(subset=['match_time', 'home']).sort_values('match_time')\n",
    "lottery = read_data_result(os.path.join(xls_path,'lottery_resules.xls'))\n",
    "# asia_data = asia_data[asia_data.result_type != -1]\n",
    "# asia_data = asia_data.drop_duplicates(subset=['match_time', 'home']).sort_values('match_time')\n",
    "\n",
    "# 如果有新增数据，则需要运行一次\n",
    "lottery.to_pickle(os.path.join(pkl_path,'lottery_resules.pkl')) #格式另存\n",
    "euro_data.to_pickle(os.path.join(pkl_path,'euro_data_%d.pkl' % euro_data.shape[0])) \n",
    "asia_data.to_pickle(os.path.join(pkl_path,'asia_data_%d.pkl' % asia_data.shape[0])) \n",
    "zcsf_data.to_pickle(os.path.join(pkl_path,'zcsf_data_%d.pkl' % zcsf_data.shape[0])) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "euro_data = pd.read_pickle(os.path.join(pkl_path,'euro_data_24865.pkl'))\r\n",
    "asia_data = pd.read_pickle(os.path.join(pkl_path,'asia_data_35115.pkl'))\r\n",
    "zcsf_data = pd.read_pickle(os.path.join(pkl_path,'zcsf_data_4928.pkl'))\r\n",
    "lottery = pd.read_pickle(os.path.join(pkl_path,'lottery_resules.pkl'))\r\n",
    "\r\n",
    "\r\n",
    "rank_match = euro_data.merge(zcsf_data,on=['match_time','home'],how='inner').match_type.value_counts().rank(ascending=False).head(10)\r\n",
    "euro_data['match_type'] = euro_data.match_type.map(rank_match).fillna(-1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>number</th>\n",
       "      <th>match_type</th>\n",
       "      <th>match_rounds</th>\n",
       "      <th>match_time</th>\n",
       "      <th>home</th>\n",
       "      <th>result</th>\n",
       "      <th>visiting</th>\n",
       "      <th>macao</th>\n",
       "      <th>ladbrokes</th>\n",
       "      <th>bet365</th>\n",
       "      <th>hg</th>\n",
       "      <th>ysb</th>\n",
       "      <th>result_type</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.0</td>\n",
       "      <td>澳超</td>\n",
       "      <td>第1轮</td>\n",
       "      <td>2021-12-31 16:05:00</td>\n",
       "      <td>中央海</td>\n",
       "      <td>1:0</td>\n",
       "      <td>纽喷射</td>\n",
       "      <td>1.02</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.91</td>\n",
       "      <td>0.9</td>\n",
       "      <td>0.93</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1.0</td>\n",
       "      <td>澳超</td>\n",
       "      <td>第1轮</td>\n",
       "      <td>2021-12-31 16:05:00</td>\n",
       "      <td>中央海</td>\n",
       "      <td>1:0</td>\n",
       "      <td>纽喷射</td>\n",
       "      <td>受平手/半球</td>\n",
       "      <td>NaN</td>\n",
       "      <td>受半球</td>\n",
       "      <td>受半球</td>\n",
       "      <td>受半球</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1.0</td>\n",
       "      <td>澳超</td>\n",
       "      <td>第1轮</td>\n",
       "      <td>2021-12-31 16:05:00</td>\n",
       "      <td>中央海</td>\n",
       "      <td>1:0</td>\n",
       "      <td>纽喷射</td>\n",
       "      <td>0.78</td>\n",
       "      <td>NaN</td>\n",
       "      <td>1.02</td>\n",
       "      <td>0.99</td>\n",
       "      <td>1.02</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2.0</td>\n",
       "      <td>西甲</td>\n",
       "      <td>第16轮</td>\n",
       "      <td>2021-12-31 21:00:00</td>\n",
       "      <td>毕尔巴</td>\n",
       "      <td>0:1</td>\n",
       "      <td>社会</td>\n",
       "      <td>1.1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>1.16</td>\n",
       "      <td>1.14</td>\n",
       "      <td>1.25</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2.0</td>\n",
       "      <td>西甲</td>\n",
       "      <td>第16轮</td>\n",
       "      <td>2021-12-31 21:00:00</td>\n",
       "      <td>毕尔巴</td>\n",
       "      <td>0:1</td>\n",
       "      <td>社会</td>\n",
       "      <td>平手</td>\n",
       "      <td>NaN</td>\n",
       "      <td>平手</td>\n",
       "      <td>平手</td>\n",
       "      <td>平手</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   number match_type match_rounds          match_time home result visiting  \\\n",
       "0     1.0         澳超          第1轮 2021-12-31 16:05:00  中央海    1:0      纽喷射   \n",
       "1     1.0         澳超          第1轮 2021-12-31 16:05:00  中央海    1:0      纽喷射   \n",
       "2     1.0         澳超          第1轮 2021-12-31 16:05:00  中央海    1:0      纽喷射   \n",
       "3     2.0         西甲         第16轮 2021-12-31 21:00:00  毕尔巴    0:1       社会   \n",
       "4     2.0         西甲         第16轮 2021-12-31 21:00:00  毕尔巴    0:1       社会   \n",
       "\n",
       "    macao  ladbrokes bet365    hg   ysb  result_type  \n",
       "0    1.02        NaN   0.91   0.9  0.93            2  \n",
       "1  受平手/半球        NaN    受半球   受半球   受半球            2  \n",
       "2    0.78        NaN   1.02  0.99  1.02            2  \n",
       "3     1.1        NaN   1.16  1.14  1.25            0  \n",
       "4      平手        NaN     平手    平手    平手            0  "
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "asia_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "match_type                      float64\n",
       "match_rounds                     object\n",
       "match_time               datetime64[ns]\n",
       "home                             object\n",
       "result                           object\n",
       "visiting                         object\n",
       "odds_init_win                   float64\n",
       "odds_init_draw                  float64\n",
       "odds_init_lose                  float64\n",
       "odds_final_win                  float64\n",
       "odds_final_draw                 float64\n",
       "odds_final_lose                 float64\n",
       "result_type                       int64\n",
       "result_pay                      float64\n",
       "odds_final_sum                  float64\n",
       "win_minus_lose_final            float64\n",
       "win_divide_lose_final           float64\n",
       "win_divide_sum_final            float64\n",
       "draw_divide_sum_final           float64\n",
       "lose_divide_sum_final           float64\n",
       "odds_init_sum                   float64\n",
       "win_minus_lose_init             float64\n",
       "win_divide_lose_init            float64\n",
       "win_divide_sum_init             float64\n",
       "draw_divide_sum_init            float64\n",
       "lose_divide_sum_init            float64\n",
       "odds_diff_win                   float64\n",
       "odds_diff_draw                  float64\n",
       "odds_diff_lose                  float64\n",
       "win_divide_lose_diff            float64\n",
       "dtype: object"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def add_feat(data):\r\n",
    "    for col in ['final','init']:\r\n",
    "        data['odds_%s_sum'%col] = data['odds_%s_win'%col] + data['odds_%s_lose'%col] + data['odds_%s_draw'%col]\r\n",
    "        data['win_minus_lose_%s' %col] = data['odds_%s_win'%col] - data['odds_%s_lose'%col]\r\n",
    "        data['win_divide_lose_%s' % col] = data['odds_%s_win'%col] / data['odds_%s_lose'%col]\r\n",
    "        for col2 in ['win','draw','lose']:\r\n",
    "            data['%s_divide_sum_%s' % (col2,col)] = data['odds_%s_%s'%(col,col2)] / data['odds_%s_sum'%col]\r\n",
    "\r\n",
    "    for col in ['win','draw','lose']:\r\n",
    "        data['odds_diff_%s' % col] = data['odds_final_%s' % col] - data['odds_init_%s' % col]\r\n",
    "    \r\n",
    "    data['win_divide_lose_diff'] = data['win_divide_lose_final'] - data['win_divide_lose_init']\r\n",
    "    return data\r\n",
    "euro_data = add_feat(euro_data)\r\n",
    "euro_data.dtypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "gid              object\n",
       "first_price_9     int64\n",
       "dtype: object"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = pd.read_excel(xfile, header=[0,1])\r\n",
    "data.head().T\r\n",
    "zcsf_data.head()\r\n",
    "read_data_result(os.path.join(xls_path,'lottery_resules.xls')).dtypes\r\n",
    "# zcsf_data.dtypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7    3026\n",
       "8    2996\n",
       "6    1796\n",
       "9    1322\n",
       "5     659\n",
       "4     170\n",
       "3      26\n",
       "2       4\n",
       "0       1\n",
       "dtype: int64"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.random.multinomial(100, [1.0 / 3, 2.0 / 3]) \r\n",
    "\r\n",
    "\r\n",
    "a = np.random.rand(10000,9) < 0.8\r\n",
    "\r\n",
    "pd.Series(a.sum(axis=1)).value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>match_type</th>\n",
       "      <th>match_rounds</th>\n",
       "      <th>match_time</th>\n",
       "      <th>home</th>\n",
       "      <th>result</th>\n",
       "      <th>visiting</th>\n",
       "      <th>result_type</th>\n",
       "      <th>home_ysb</th>\n",
       "      <th>odds_ysb</th>\n",
       "      <th>away_ysb</th>\n",
       "      <th>home_hg</th>\n",
       "      <th>odds_hg</th>\n",
       "      <th>away_hg</th>\n",
       "      <th>home_bet365</th>\n",
       "      <th>odds_bet365</th>\n",
       "      <th>away_bet365</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>澳超</td>\n",
       "      <td>第1轮</td>\n",
       "      <td>2021-12-31 16:05:00</td>\n",
       "      <td>中央海</td>\n",
       "      <td>1:0</td>\n",
       "      <td>纽喷射</td>\n",
       "      <td>2</td>\n",
       "      <td>0.93</td>\n",
       "      <td>受半球</td>\n",
       "      <td>1.02</td>\n",
       "      <td>0.90</td>\n",
       "      <td>受半球</td>\n",
       "      <td>0.99</td>\n",
       "      <td>0.910</td>\n",
       "      <td>受半球</td>\n",
       "      <td>1.020</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>西甲</td>\n",
       "      <td>第16轮</td>\n",
       "      <td>2021-12-31 21:00:00</td>\n",
       "      <td>毕尔巴</td>\n",
       "      <td>0:1</td>\n",
       "      <td>社会</td>\n",
       "      <td>0</td>\n",
       "      <td>1.25</td>\n",
       "      <td>平手</td>\n",
       "      <td>0.75</td>\n",
       "      <td>1.14</td>\n",
       "      <td>平手</td>\n",
       "      <td>0.77</td>\n",
       "      <td>1.160</td>\n",
       "      <td>平手</td>\n",
       "      <td>0.780</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>西甲</td>\n",
       "      <td>第16轮</td>\n",
       "      <td>2021-12-31 23:15:00</td>\n",
       "      <td>奥萨苏</td>\n",
       "      <td>1:1</td>\n",
       "      <td>阿拉维</td>\n",
       "      <td>1</td>\n",
       "      <td>1.06</td>\n",
       "      <td>平手/半球</td>\n",
       "      <td>0.90</td>\n",
       "      <td>1.02</td>\n",
       "      <td>平手/半球</td>\n",
       "      <td>0.88</td>\n",
       "      <td>1.020</td>\n",
       "      <td>平手/半球</td>\n",
       "      <td>0.910</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>天皇杯</td>\n",
       "      <td>决赛</td>\n",
       "      <td>2021-01-01 13:40:00</td>\n",
       "      <td>川崎</td>\n",
       "      <td>1:0</td>\n",
       "      <td>大阪</td>\n",
       "      <td>2</td>\n",
       "      <td>0.92</td>\n",
       "      <td>一球</td>\n",
       "      <td>0.96</td>\n",
       "      <td>0.90</td>\n",
       "      <td>一球</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.875</td>\n",
       "      <td>一球</td>\n",
       "      <td>0.975</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>英超</td>\n",
       "      <td>第17轮</td>\n",
       "      <td>2021-01-02 01:30:00</td>\n",
       "      <td>埃弗顿</td>\n",
       "      <td>0:1</td>\n",
       "      <td>西汉姆</td>\n",
       "      <td>0</td>\n",
       "      <td>1.00</td>\n",
       "      <td>平手/半球</td>\n",
       "      <td>0.96</td>\n",
       "      <td>0.97</td>\n",
       "      <td>平手/半球</td>\n",
       "      <td>0.93</td>\n",
       "      <td>0.970</td>\n",
       "      <td>平手/半球</td>\n",
       "      <td>0.930</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  match_type match_rounds          match_time home result visiting  \\\n",
       "0         澳超          第1轮 2021-12-31 16:05:00  中央海    1:0      纽喷射   \n",
       "1         西甲         第16轮 2021-12-31 21:00:00  毕尔巴    0:1       社会   \n",
       "2         西甲         第16轮 2021-12-31 23:15:00  奥萨苏    1:1      阿拉维   \n",
       "3        天皇杯           决赛 2021-01-01 13:40:00   川崎    1:0       大阪   \n",
       "4         英超         第17轮 2021-01-02 01:30:00  埃弗顿    0:1      西汉姆   \n",
       "\n",
       "   result_type  home_ysb odds_ysb  away_ysb  home_hg odds_hg  away_hg  \\\n",
       "0            2      0.93      受半球      1.02     0.90     受半球     0.99   \n",
       "1            0      1.25       平手      0.75     1.14      平手     0.77   \n",
       "2            1      1.06    平手/半球      0.90     1.02   平手/半球     0.88   \n",
       "3            2      0.92       一球      0.96     0.90      一球     1.00   \n",
       "4            0      1.00    平手/半球      0.96     0.97   平手/半球     0.93   \n",
       "\n",
       "   home_bet365 odds_bet365  away_bet365  \n",
       "0        0.910         受半球        1.020  \n",
       "1        1.160          平手        0.780  \n",
       "2        1.020       平手/半球        0.910  \n",
       "3        0.875          一球        0.975  \n",
       "4        0.970       平手/半球        0.930  "
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def pivot_asia_bet365(x):\r\n",
    "    col = 'bet365'\r\n",
    "    map_index = {0: \"home_%s\" % col, 1: \"odds_%s\" % col, 2: \"away_%s\" % col}\r\n",
    "    return x.loc[:,[col]].reset_index(drop=True).rename(index=map_index).T\r\n",
    "\r\n",
    "def pivot_asia_ysb(x):\r\n",
    "    col = 'ysb'\r\n",
    "    map_index = {0: \"home_%s\" % col, 1: \"odds_%s\" % col, 2: \"away_%s\" % col}\r\n",
    "    return x.loc[:,[col]].reset_index(drop=True).rename(index=map_index).T\r\n",
    "\r\n",
    "def pivot_asia_hg(x):\r\n",
    "    col = 'hg'\r\n",
    "    map_index = {0: \"home_%s\" % col, 1: \"odds_%s\" % col, 2: \"away_%s\" % col}\r\n",
    "    return x.loc[:,[col]].reset_index(drop=True).rename(index=map_index).T\r\n",
    "\r\n",
    "# asia_data['match_id'] = asia_data.apply(lambda x: x['match_time'] + '-' + x['home'], axis=1)\r\n",
    "a = asia_data.groupby(['match_time','home']).apply(pivot_asia_ysb).reset_index().drop(columns='level_2')\r\n",
    "b = asia_data.groupby(['match_time','home']).apply(pivot_asia_hg).reset_index().drop(columns='level_2')\r\n",
    "c = asia_data.groupby(['match_time','home']).apply(pivot_asia_bet365).reset_index().drop(columns='level_2')\r\n",
    "\r\n",
    "a = a.convert_dtypes()\r\n",
    "b = b.convert_dtypes()\r\n",
    "c = c.convert_dtypes()\r\n",
    "\r\n",
    "un_feat_cols = ['match_type', 'match_rounds', 'match_time', 'home', 'result', 'visiting']\r\n",
    "\r\n",
    "asia_data = asia_data.loc[:,un_feat_cols + ['result_type']].drop_duplicates().merge( \\\r\n",
    "            a, on=['match_time','home']).merge( \\\r\n",
    "            b, on=['match_time','home']).merge(c, on=['match_time','home'])\r\n",
    "asia_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "----------follow_max_odds----------\n",
      "           bet_return        bet_comp\n",
      "                 mean count      mean\n",
      "bet_odds                             \n",
      "(3.1, 3.2]   1.038333   324  0.327160\n",
      "(4.6, 5.4]   1.007120   316  0.202532\n",
      "----------follow_midele_odds----------\n",
      "            bet_return        bet_comp\n",
      "                  mean count      mean\n",
      "bet_odds                              \n",
      "(2.8, 2.9]    1.022906   320  0.359375\n",
      "(4.6, 25.6]   1.066324   321  0.186916\n",
      "----------follow_min_odds----------\n",
      "           bet_return        bet_comp\n",
      "                 mean count      mean\n",
      "bet_odds                             \n",
      "(1.7, 1.8]   1.041024   332  0.584337\n",
      "(2.2, 2.3]   1.017125   313  0.447284\n",
      "----------always_home_win----------\n",
      "           bet_return        bet_comp\n",
      "                 mean count      mean\n",
      "bet_odds                             \n",
      "(1.5, 1.7]   1.019731   335  0.647761\n",
      "(1.7, 1.8]   1.053609   302  0.599338\n",
      "----------always_home_draw----------\n",
      "            bet_return        bet_comp\n",
      "                  mean count      mean\n",
      "bet_odds                              \n",
      "(3.0, 3.1]    1.060909   341  0.348974\n",
      "(3.6, 3.7]    1.078987   316  0.297468\n",
      "(4.6, 25.6]   1.066324   321  0.186916\n",
      "----------always_home_lose----------\n",
      "           bet_return        bet_comp\n",
      "                 mean count      mean\n",
      "bet_odds                             \n",
      "(1.9, 2.2]   1.047951   327  0.507645\n",
      "(2.2, 2.5]   1.023531   320  0.434375\n"
     ]
    }
   ],
   "source": [
    "def follow_max_odds(x):\r\n",
    "    wo,do,lo = x['odds_final_win'],x['odds_final_draw'],x['odds_final_lose']\r\n",
    "    result = x['result_type']\r\n",
    "    if wo == max( [wo,do,lo]):\r\n",
    "        return pd.DataFrame(data={'bet_odds':[wo],\r\n",
    "                                  'bet_comp':[int(result == 2)],\r\n",
    "                                  'bet_prob':[1]})\r\n",
    "    elif do == max([do,lo]):\r\n",
    "        return pd.DataFrame(data={'bet_odds':[do],\r\n",
    "                                  'bet_comp':[int(result == 1)],\r\n",
    "                                  'bet_prob':[1]})\r\n",
    "    else:\r\n",
    "        return pd.DataFrame(data={'bet_odds':[lo],\r\n",
    "                                  'bet_comp':[int(result == 0)],\r\n",
    "                                  'bet_prob':[1]})\r\n",
    "\r\n",
    "def follow_midele_odds(x):\r\n",
    "    wo,do,lo = x['odds_final_win'],x['odds_final_draw'],x['odds_final_lose']\r\n",
    "    result = x['result_type']\r\n",
    "    if wo == np.median( [wo,do,lo]):\r\n",
    "        return pd.DataFrame(data={'bet_odds':[wo],'bet_comp':[int(result == 2)]})\r\n",
    "    elif do == np.median( [wo,do,lo]):\r\n",
    "        return pd.DataFrame(data={'bet_odds':[do],'bet_comp':[int(result == 1)]})\r\n",
    "    else:\r\n",
    "        return pd.DataFrame(data={'bet_odds':[lo],'bet_comp':[int(result == 0)]})\r\n",
    "    return \r\n",
    "\r\n",
    "def follow_min_odds(x):\r\n",
    "    wo,do,lo = x['odds_final_win'],x['odds_final_draw'],x['odds_final_lose']\r\n",
    "    result = x['result_type']\r\n",
    "    if wo == min( [wo,do,lo]):\r\n",
    "        return pd.DataFrame(data={'bet_odds':[wo],'bet_comp':[int(result == 2)]})\r\n",
    "    elif do == min([do,lo]):\r\n",
    "        return pd.DataFrame(data={'bet_odds':[do],'bet_comp':[int(result == 1)]})\r\n",
    "    else:\r\n",
    "        return pd.DataFrame(data={'bet_odds':[lo],'bet_comp':[int(result == 0)]})\r\n",
    "    return \r\n",
    "\r\n",
    "def always_home_win(x):\r\n",
    "    wo,do,lo = x['odds_final_win'],x['odds_final_draw'],x['odds_final_lose']\r\n",
    "    result = x['result_type']\r\n",
    "    return pd.DataFrame(data={'bet_odds':[wo],'bet_comp':[int(result == 2)]})\r\n",
    "\r\n",
    "def always_home_draw(x):\r\n",
    "    wo,do,lo = x['odds_final_win'],x['odds_final_draw'],x['odds_final_lose']\r\n",
    "    result = x['result_type']\r\n",
    "    return pd.DataFrame(data={'bet_odds':[do],'bet_comp':[int(result == 1)]})\r\n",
    "\r\n",
    "def always_home_lose(x):\r\n",
    "    wo,do,lo = x['odds_final_win'],x['odds_final_draw'],x['odds_final_lose']\r\n",
    "    result = x['result_type']\r\n",
    "    return pd.DataFrame(data={'bet_odds':[lo],'bet_comp':[int(result == 0)]})\r\n",
    "\r\n",
    "\r\n",
    "strategies = [follow_max_odds, follow_midele_odds, follow_min_odds, always_home_win, always_home_draw, always_home_lose]\r\n",
    "\r\n",
    "def run_strategy(data, strategy):\r\n",
    "    d = data.apply(strategy, axis=1)\r\n",
    "    d = pd.concat(d.tolist(), axis=0).reset_index(drop=True)\r\n",
    "    d['bet_return'] = d['bet_odds'] * d['bet_comp']\r\n",
    "    # print(str(strategy), (d['bet_odds'] * d['bet_comp']).sum() / d.shape[0])\r\n",
    "    print('-' * 10 + strategy.__name__ + '-' * 10)\r\n",
    "    metrics = d.groupby(pd.qcut(d['bet_odds'],10,precision=0)).agg({'bet_return':['mean','count'],'bet_comp':'mean'})\r\n",
    "    print(metrics[metrics.iloc[:,0] > 1.0])\r\n",
    "\r\n",
    "\r\n",
    "for strategy in strategies:\r\n",
    "    run_strategy(euro_data.copy(), strategy)\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "d = euro_data.apply(always_home_draw, axis=1)\r\n",
    "d = pd.concat(d.tolist(), axis=0).reset_index(drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">bet_return</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>mean</th>\n",
       "      <th>count</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>bet_odds</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>(2.0, 3.0]</th>\n",
       "      <td>0.911246</td>\n",
       "      <td>321</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(3.0, 3.1]</th>\n",
       "      <td>1.060909</td>\n",
       "      <td>341</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(3.1, 3.2]</th>\n",
       "      <td>0.974506</td>\n",
       "      <td>324</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(3.2, 3.3]</th>\n",
       "      <td>0.971614</td>\n",
       "      <td>316</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(3.3, 3.4]</th>\n",
       "      <td>0.852664</td>\n",
       "      <td>304</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(3.4, 3.6]</th>\n",
       "      <td>0.876350</td>\n",
       "      <td>326</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(3.6, 3.7]</th>\n",
       "      <td>1.078987</td>\n",
       "      <td>316</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(3.7, 4.0]</th>\n",
       "      <td>0.890404</td>\n",
       "      <td>322</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(4.0, 4.6]</th>\n",
       "      <td>0.758297</td>\n",
       "      <td>317</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(4.6, 25.6]</th>\n",
       "      <td>1.066324</td>\n",
       "      <td>321</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            bet_return      \n",
       "                  mean count\n",
       "bet_odds                    \n",
       "(2.0, 3.0]    0.911246   321\n",
       "(3.0, 3.1]    1.060909   341\n",
       "(3.1, 3.2]    0.974506   324\n",
       "(3.2, 3.3]    0.971614   316\n",
       "(3.3, 3.4]    0.852664   304\n",
       "(3.4, 3.6]    0.876350   326\n",
       "(3.6, 3.7]    1.078987   316\n",
       "(3.7, 4.0]    0.890404   322\n",
       "(4.0, 4.6]    0.758297   317\n",
       "(4.6, 25.6]   1.066324   321"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d['bet_return'] = d['bet_odds'] * d['bet_comp']\r\n",
    "d.groupby(pd.qcut(d['bet_odds'],10,precision=0)).agg({'bet_return':['mean','count']})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['away_hg', 'odds_ysb', 'odds_bet365', 'odds_hg', 'away_bet365', 'home_ysb', 'away_ysb', 'home_bet365', 'home_hg']\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/lightgbm/basic.py:1286: UserWarning: Overriding the parameters from Reference Dataset.\n",
      "  warnings.warn('Overriding the parameters from Reference Dataset.')\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/lightgbm/basic.py:1098: UserWarning: categorical_column in param dict is overridden.\n",
      "  warnings.warn('{} in param dict is overridden.'.format(cat_alias))\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 65  45  39   0]\n",
      " [ 40  39  42   1]\n",
      " [ 62  62 122   1]\n",
      " [  0   0   1   0]]\n",
      "0.43545279383429675\n"
     ]
    }
   ],
   "source": [
    "import lightgbm as lgb\r\n",
    "import numpy as np\r\n",
    "# from pandas.tseries.offsets import MonthEnd, MonthBegin\r\n",
    "from sklearn.model_selection import train_test_split\r\n",
    "\r\n",
    "from sklearn.metrics import mean_squared_error, accuracy_score, confusion_matrix\r\n",
    "from sklearn.model_selection import KFold\r\n",
    "\r\n",
    "target_col = 'result_type'\r\n",
    "\r\n",
    "un_feat_cols = ['match_type', 'match_rounds', 'match_time', 'home', 'result',\r\n",
    "       'visiting', ]\r\n",
    "\r\n",
    "\r\n",
    "feat_cols = list(set(asia_data.columns) - set(un_feat_cols) - set([target_col]))\r\n",
    "print(feat_cols)\r\n",
    "asia_data['odds_ysb'] = asia_data['odds_ysb'].astype(\"category\")\r\n",
    "asia_data['odds_hg'] = asia_data['odds_hg'].astype(\"category\")\r\n",
    "asia_data['odds_bet365'] = asia_data['odds_bet365'].astype(\"category\")\r\n",
    "\r\n",
    "X_train, X_test, y_train, y_test = train_test_split(asia_data.loc[:,feat_cols], asia_data[target_col],test_size=.3,random_state =0)\r\n",
    "\r\n",
    "\r\n",
    "model = lgb.LGBMClassifier(random_state=1212)\r\n",
    "\r\n",
    "lgb_model = model.fit(X_train, y_train, \\\r\n",
    "                      eval_names=['train', 'valid'], \\\r\n",
    "                      eval_set=[(X_train, y_train), (X_test, y_test)],\\\r\n",
    "                      early_stopping_rounds=100,\\\r\n",
    "                    #   eval_metric='softmax',\r\n",
    "                      verbose=0)\r\n",
    "print(confusion_matrix(lgb_model.predict(X_test, num_iteration=lgb_model.best_iteration_), y_test) )\r\n",
    "print(accuracy_score(lgb_model.predict(X_test, num_iteration=lgb_model.best_iteration_), y_test) )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f64418e0290>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_importance(lgb_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.1->0.6299->0.4965\n",
      "0.2->0.6531->0.4948\n",
      "0.3->0.6777->0.5193\n",
      "0.4->0.7046->0.5311\n",
      "0.5->0.7354->0.5509\n",
      "0.6->0.7694->0.5662\n",
      "0.7->0.8084->0.5848\n",
      "0.8->0.8543->0.6166\n",
      "0.9->0.9103->0.6804\n"
     ]
    }
   ],
   "source": [
    "preds = np.zeros((X_test.shape[0],2))\r\n",
    "preds[:,0] = lgb_model.predict_proba(X_test, num_iteration=lgb_model.best_iteration_).max(1)\r\n",
    "preds[:,1] = lgb_model.predict(X_test, num_iteration=lgb_model.best_iteration_)\r\n",
    "# for pd.Series(preds[:,0]).quantile(0.1)\r\n",
    "\r\n",
    "for q in np.arange(0.1,1,0.1):\r\n",
    "    idx = preds[:,0] > np.quantile(preds[:,0],q=q)\r\n",
    "    print('->'.join(map(lambda x: str(round(x,4)),[q,preds[idx,0].mean(), accuracy_score(preds[idx,1], y_test[idx])])))\r\n",
    "    # print(confusion_matrix(preds[idx,1], y_test[idx]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# !python -m pip install -q \"featuretools\"\r\n",
    "!pip install -q lightgbm\r\n",
    "# !pip install -q autofeat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['win_divide_lose_init', 'odds_init_win', 'odds_final_draw', 'odds_final_sum', 'odds_diff_lose', 'lose_divide_sum_final', 'odds_init_lose', 'win_divide_sum_init', 'win_divide_sum_final', 'odds_diff_draw', 'draw_divide_sum_final', 'odds_final_win', 'win_divide_lose_final', 'odds_init_sum', 'win_divide_lose_diff', 'win_minus_lose_init', 'lose_divide_sum_init', 'odds_final_lose', 'match_type', 'draw_divide_sum_init', 'win_minus_lose_final', 'odds_init_draw', 'odds_diff_win']\n",
      "(19649, 31) (24865, 30)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/lightgbm/basic.py:1286: UserWarning: Overriding the parameters from Reference Dataset.\n",
      "  warnings.warn('Overriding the parameters from Reference Dataset.')\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/lightgbm/basic.py:1098: UserWarning: categorical_column in param dict is overridden.\n",
      "  warnings.warn('{} in param dict is overridden.'.format(cat_alias))\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1035  561  544]\n",
      " [ 154  133  163]\n",
      " [ 717  836 1752]]\n",
      "0.4953350296861747\n"
     ]
    }
   ],
   "source": [
    "target_col = 'result_type'\r\n",
    "\r\n",
    "un_feat_cols = [ 'match_rounds', 'match_time', 'home', 'result',\r\n",
    "       'visiting', 'result_pay'] # 'match_type',\r\n",
    "\r\n",
    "euro_data['match_type'] = euro_data['match_type'].astype('category')\r\n",
    "feat_cols_euro = list(set(euro_data.columns) - set(un_feat_cols) - set([target_col]))\r\n",
    "print(feat_cols_euro)\r\n",
    "euro_data_feed = euro_data.merge(zcsf_data.drop('gid',axis=1), on=['match_time','home'], how=\"outer\", indicator=True).query('_merge==\"left_only\"')\r\n",
    "euro_data_feed = euro_data_feed[euro_data_feed.result_type != -1]\r\n",
    "\r\n",
    "print(euro_data_feed.shape, euro_data.shape)\r\n",
    "X_train, X_test, y_train, y_test = train_test_split(euro_data_feed.loc[:,:], \\\r\n",
    "                                                    euro_data_feed[target_col],test_size=.3,random_state =122)\r\n",
    "\r\n",
    "\r\n",
    "model = lgb.LGBMClassifier(random_state=1212)\r\n",
    "\r\n",
    "lgb_model = model.fit(X_train.loc[:,feat_cols_euro], y_train, \\\r\n",
    "                      eval_names=['train', 'valid'], \\\r\n",
    "                      eval_set=[(X_train.loc[:,feat_cols_euro], y_train), (X_test.loc[:,feat_cols_euro], y_test)],\\\r\n",
    "                      early_stopping_rounds=100,\\\r\n",
    "                    #   eval_metric='softmax',\r\n",
    "                      verbose=0)\r\n",
    "\r\n",
    "# lgb_model = joblib.load('./work/models/euro_0.6042_2021-08-26.pkl')\r\n",
    "print(confusion_matrix(lgb_model.predict(X_test.loc[:,feat_cols_euro], num_iteration=lgb_model.best_iteration_), y_test) )\r\n",
    "print(accuracy_score(lgb_model.predict(X_test.loc[:,feat_cols_euro], num_iteration=lgb_model.best_iteration_), y_test) )\r\n",
    "# score=run_lgb(data,feat_cols,target_col)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.5466231381350745, 0.7926953682921852)"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_val = euro_data.merge(zcsf_data,on=['match_time','home'],how='inner')\r\n",
    "X_val = X_val[X_val.result_type != -1]\r\n",
    "# X_val = X_val[X_val.match_time < '2020-12-31']\r\n",
    "pred_prob = lgb_model.predict_proba(X_val.loc[:,feat_cols_euro], num_iteration=lgb_model.best_iteration_)\r\n",
    "pred_cls = lgb_model.predict(X_val.loc[:,feat_cols_euro], num_iteration=lgb_model.best_iteration_)\r\n",
    "# joblib.dump(lgb_model, './work/models/euro_%.4f_%s.pkl' % (accuracy_score(pred_cls, X_val[target_col]), str(datetime.datetime.now())[:10]))\r\n",
    "accuracy_score(pred_cls, X_val[target_col]), 1- accuracy_score(pred_prob.argmin(1), X_val[target_col])\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training fold 1\n",
      "[LightGBM] [Warning] Auto-choosing row-wise multi-threading, the overhead of testing was 0.000769 seconds.\n",
      "You can set `force_row_wise=true` to remove the overhead.\n",
      "And if memory is not enough, you can set `force_col_wise=true`.\n",
      "Training until validation scores don't improve for 100 rounds\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/lightgbm/basic.py:1286: UserWarning: Overriding the parameters from Reference Dataset.\n",
      "  warnings.warn('Overriding the parameters from Reference Dataset.')\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/lightgbm/basic.py:1098: UserWarning: categorical_column in param dict is overridden.\n",
      "  warnings.warn('{} in param dict is overridden.'.format(cat_alias))\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Did not meet early stopping. Best iteration is:\n",
      "[100]\ttraining's multi_logloss: 0.963824\tvalid_1's multi_logloss: 1.01356\n",
      "Training fold 2\n",
      "[LightGBM] [Warning] Auto-choosing row-wise multi-threading, the overhead of testing was 0.000741 seconds.\n",
      "You can set `force_row_wise=true` to remove the overhead.\n",
      "And if memory is not enough, you can set `force_col_wise=true`.\n",
      "Training until validation scores don't improve for 100 rounds\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[100]\ttraining's multi_logloss: 0.961124\tvalid_1's multi_logloss: 1.01926\n",
      "Training fold 3\n",
      "[LightGBM] [Warning] Auto-choosing row-wise multi-threading, the overhead of testing was 0.000754 seconds.\n",
      "You can set `force_row_wise=true` to remove the overhead.\n",
      "And if memory is not enough, you can set `force_col_wise=true`.\n",
      "Training until validation scores don't improve for 100 rounds\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[100]\ttraining's multi_logloss: 0.963323\tvalid_1's multi_logloss: 1.01438\n",
      "Training fold 4\n",
      "[LightGBM] [Warning] Auto-choosing row-wise multi-threading, the overhead of testing was 0.000732 seconds.\n",
      "You can set `force_row_wise=true` to remove the overhead.\n",
      "And if memory is not enough, you can set `force_col_wise=true`.\n",
      "Training until validation scores don't improve for 100 rounds\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[100]\ttraining's multi_logloss: 0.960148\tvalid_1's multi_logloss: 1.02294\n",
      "Training fold 5\n",
      "[LightGBM] [Warning] Auto-choosing row-wise multi-threading, the overhead of testing was 0.000751 seconds.\n",
      "You can set `force_row_wise=true` to remove the overhead.\n",
      "And if memory is not enough, you can set `force_col_wise=true`.\n",
      "Training until validation scores don't improve for 100 rounds\n",
      "Did not meet early stopping. Best iteration is:\n",
      "[100]\ttraining's multi_logloss: 0.961094\tvalid_1's multi_logloss: 1.01642\n",
      "0.49156608986476663\n",
      "0.5097540288379983 0.5639665374413385\n"
     ]
    }
   ],
   "source": [
    "def train_and_evaluate_lgb(train, test, val, params, features):\r\n",
    "    # Hyperparammeters (just basic)\r\n",
    "    \r\n",
    "    y = train['result_type']\r\n",
    "    oof_predictions = np.zeros((train.shape[0],3))\r\n",
    "    test_predictions = np.zeros((test.shape[0],3))\r\n",
    "    val_predictions = np.zeros((val.shape[0],3))\r\n",
    "    kfold = KFold(n_splits = 5, random_state = 2021, shuffle = True)\r\n",
    "    for fold, (trn_ind, val_ind) in enumerate(kfold.split(train)):\r\n",
    "        print(f'Training fold {fold + 1}')\r\n",
    "        x_train, x_val = train.iloc[trn_ind], train.iloc[val_ind]\r\n",
    "        y_train, y_val = y.iloc[trn_ind], y.iloc[val_ind]\r\n",
    "        # Root mean squared percentage error weights\r\n",
    "        train_weights = 1 / np.square(y_train)\r\n",
    "        val_weights = 1 / np.square(y_val)\r\n",
    "        train_dataset = lgb.Dataset(x_train[features], y_train) # , weight = train_weights)\r\n",
    "        val_dataset = lgb.Dataset(x_val[features], y_val) # , weight = val_weights)\r\n",
    "        model = lgb.train(params = params,\r\n",
    "                          train_set = train_dataset, \r\n",
    "                          valid_sets = [train_dataset, val_dataset], \r\n",
    "                          early_stopping_rounds=100,\r\n",
    "                          verbose_eval = -1,\r\n",
    "                          )\r\n",
    "\r\n",
    "        oof_predictions[val_ind] = model.predict(x_val[features])\r\n",
    "        test_predictions += model.predict(test[features]) / 5\r\n",
    "        val_predictions += model.predict(val[features]) / 5\r\n",
    "    print(accuracy_score(y, oof_predictions.argmax(axis=1)))\r\n",
    "    # print(f'Our out of folds RMSPE is {rmspe_score}')\r\n",
    "    # lgb.plot_importance(model,max_num_features=20)\r\n",
    "    # Return test predictions\r\n",
    "    return test_predictions, val_predictions\r\n",
    "# Traing and evaluate\r\n",
    "params0 = {\r\n",
    "    'learning_rate': 0.015,\r\n",
    "    # 'metric': 'multi_error',\r\n",
    "    'objective': 'multiclass', # 'multiclass','multiclassova'\r\n",
    "    'num_class':3,\r\n",
    "    'verbose':0, \r\n",
    "    'lambda_l2':0.1,\r\n",
    "    'boosting': 'gbdt',\r\n",
    "\r\n",
    "}\r\n",
    "X_val = euro_data.merge(zcsf_data,on=['match_time','home'],how='inner')\r\n",
    "X_val = X_val[X_val.result_type != -1]\r\n",
    "y_val = X_val[target_col]\r\n",
    "test_pred, val_pred = train_and_evaluate_lgb(X_train, X_test, X_val, params0, feat_cols_euro)\r\n",
    "print(accuracy_score(y_test, test_pred.argmax(axis=1)), accuracy_score(y_val, val_pred.argmax(axis=1)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:2: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  \n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:3: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  This is separate from the ipykernel package so we can avoid doing imports until\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:5: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  \"\"\"\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:6: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  \n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:7: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  import sys\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:8: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  \n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:9: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  if __name__ == '__main__':\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:10: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  # Remove the CWD from sys.path while we load stuff.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>comp1</th>\n",
       "      <th>comp2</th>\n",
       "      <th>match_rounds</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min_odds</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.708299</td>\n",
       "      <td>0.707477</td>\n",
       "      <td>1217</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.546889</td>\n",
       "      <td>0.514461</td>\n",
       "      <td>1141</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.466052</td>\n",
       "      <td>0.402347</td>\n",
       "      <td>1193</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.440375</td>\n",
       "      <td>0.328790</td>\n",
       "      <td>1174</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.381197</td>\n",
       "      <td>0.305128</td>\n",
       "      <td>1170</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             comp1     comp2  match_rounds\n",
       "min_odds                                  \n",
       "0         0.708299  0.707477          1217\n",
       "1         0.546889  0.514461          1141\n",
       "2         0.466052  0.402347          1193\n",
       "3         0.440375  0.328790          1174\n",
       "4         0.381197  0.305128          1170"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# X_test.sample(14,replace=False)\r\n",
    "X_test['probmax'] = test_pred.max(axis=1)\r\n",
    "X_test['min_odds'] = X_test.loc[:,['odds_final_lose','odds_final_draw','odds_final_win']].values.min(axis=1)\r\n",
    "\r\n",
    "X_test['argmax'] = test_pred.argmax(axis=1)\r\n",
    "X_test['argmin'] = test_pred.argmin(axis=1)\r\n",
    "X_test['argmid'] = np.argsort(test_pred,1)[:,1]\r\n",
    "X_test['argmax_odds'] = X_test.loc[:,['odds_final_win','odds_final_draw','odds_final_lose']].values.argmax(axis=1)\r\n",
    "X_test['comp1'] = X_test['result_type'] == X_test['argmax']\r\n",
    "X_test['comp2'] = X_test['result_type'] == X_test['argmax_odds']\r\n",
    "\r\n",
    "\r\n",
    "X_test.groupby(pd.qcut(X_test['min_odds'],5, precision=0, labels=False)).agg({'comp1':'mean','comp2':'mean','match_rounds':'count'})\r\n",
    "# X_test.head().T\r\n",
    "# X_test[X_test.min_odds < 1.5].sample(5).T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/ipykernel_launcher.py:3: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  This is separate from the ipykernel package so we can avoid doing imports until\n"
     ]
    }
   ],
   "source": [
    "ser, bins = pd.qcut(pd.concat([pd.Series(test_pred.max(1)), pd.Series(val_pred.max(1))]), 10, labels=False,retbins=True)\r\n",
    "X_val['bins'] = pd.cut(pd.Series(val_pred.max(1)), bins=bins, labels=False, include_lowest=True).values\r\n",
    "X_test['bins'] = pd.cut(pd.Series(test_pred.max(1)), bins=bins, labels=False , include_lowest=True).values\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5839     0\n",
       "3420     1\n",
       "17104    7\n",
       "8189     7\n",
       "12800    8\n",
       "Name: bins, dtype: int64"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_test.bins.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# X_val = euro_data.merge(zcsf_data,on=['match_time','home'],how='inner')\r\n",
    "# X_val = X_val[X_val.result_type != -1]\r\n",
    "# pred_prob = lgb_model.predict_proba(X_val.loc[:,feat_cols_euro], num_iteration=lgb_model.best_iteration_)\r\n",
    "# pred_cls = lgb_model.predict(X_val.loc[:,feat_cols_euro], num_iteration=lgb_model.best_iteration_)\r\n",
    "# pred_cls = val_pred.argmax(axis=1)\r\n",
    "# joblib.dump(lgb_model, './work/models/euro_%.4f_%s.pkl' % (accuracy_score(pred_cls, X_val[target_col]), str(datetime.datetime.now())[:10]))\r\n",
    "print( accuracy_score(val_pred.argmax(axis=1), X_val[target_col]), 1- accuracy_score(val_pred.argmin(1), X_val[target_col]))\r\n",
    "\r\n",
    "# val_pred = pred_prob\r\n",
    "X_val['argmin'] = val_pred.argmin(axis=1)\r\n",
    "X_val['argmax'] = val_pred.argmax(axis=1)\r\n",
    "X_val['argmid'] = np.argsort(val_pred,1)[:,1]\r\n",
    "X_val['probmax'] = val_pred.max(axis=1)\r\n",
    "\r\n",
    "\r\n",
    "X_val['comp1'] = X_val['result_type'] == X_val['argmax']\r\n",
    "X_val['comp2'] = X_val['result_type'] != X_val['argmin']\r\n",
    "X_val.groupby('bins').mean()['probmax']\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 生成模型的训练数据，模型为了预测该策略是否会成功\r\n",
    "from sklearn.ensemble import RandomForestClassifier\r\n",
    "from sklearn import linear_model\r\n",
    "from sklearn.metrics import f1_score, confusion_matrix, precision_score\r\n",
    "\r\n",
    "def fun1(x,s): # 生成训练数据\r\n",
    "    list_seq, list_res, amounts = [], [], []\r\n",
    "    for i in tqdm_notebook(range(100),total=100):\r\n",
    "        sample = x.sample(14, replace=False)\r\n",
    "        sample['gid'] = '%.5d' % i\r\n",
    "        seq, res, amount, _, _, _, _ = fun2(sample, s)\r\n",
    "        list_seq.append(seq)\r\n",
    "        list_res.append(res)\r\n",
    "        amounts.append(amount)\r\n",
    "    return np.vstack(list_seq), np.array(list_res), np.array(amounts)\r\n",
    "\r\n",
    "def fun2(x,s): # 返回策略对应的序列\r\n",
    "    # assert x.shape[0] == 14\r\n",
    "    assert len(s) == 10\r\n",
    "    x_sorted = x.sort_values('probmax',ascending=False).head(9).copy()\r\n",
    "    # print(x_sorted.loc[:['probmax','bins']])\r\n",
    "    x_sorted['s'] = x_sorted.bins.map(lambda x:s[x])\r\n",
    "    def generate_bet(x):\r\n",
    "        if x['s'] == 0:\r\n",
    "            return [x['argmax']]\r\n",
    "        elif x['s'] == 1:\r\n",
    "            return [x['argmax'],x['argmid']]\r\n",
    "        elif x['s'] == 2:\r\n",
    "            return [x['argmax'],x['argmid'],x['argmin']]\r\n",
    "    x_sorted['bet'] = x_sorted.apply(generate_bet, axis=1)\r\n",
    "    return (x_sorted.bins.values.reshape((1,-1)), \\\r\n",
    "            x_sorted.apply(lambda x: x.result_type in x.bet, axis=1).all(),\\\r\n",
    "            np.prod(x_sorted.bet.map(len).values)*2, \\\r\n",
    "            x_sorted['gid'].values[0],\\\r\n",
    "            x_sorted['bet'].values,\\\r\n",
    "            x_sorted['home'].values,\\\r\n",
    "            x_sorted['result_type'].values,\\\r\n",
    "            )\r\n",
    "\r\n",
    "\r\n",
    "def fun3(X_val): # \r\n",
    "    seq, res, amounts = fun1(X_val,[2]*5 + [1]*5 + [0]*0)\r\n",
    "    print(seq.shape, res.shape)\r\n",
    "    X_train, X_test, y_train, y_test = train_test_split(seq, res, test_size=.3,random_state =0)\r\n",
    "    # model = RandomForestClassifier()\r\n",
    "    model = linear_model.LinearRegression()\r\n",
    "    model.fit(X_train, y_train)\r\n",
    "    # print(model.predict(X_train))\r\n",
    "    print('threshold, accuracy, precision, f1, 1_mean, res_mean, amounts_mean')\r\n",
    "    for threshold in np.linspace(0.0,0.9,10):\r\n",
    "        \r\n",
    "        print('%.1f' % threshold, \r\n",
    "          '%.3f' % accuracy_score(model.predict(X_test) > threshold, y_test), \\\r\n",
    "          '%.3f' % precision_score(model.predict(X_test) > threshold, y_test), \\\r\n",
    "          '%.3f' % f1_score(model.predict(X_test) > threshold, y_test), \\\r\n",
    "          '%.2f' % np.mean(model.predict(X_test) > threshold), \\\r\n",
    "          '%.2f' % np.mean(res), \\\r\n",
    "          '%.2f' % np.mean(amounts),\\\r\n",
    "          )\r\n",
    "    return model,X_test\r\n",
    "\r\n",
    "def fun4(X_val, model):\r\n",
    "    s = [2]*5 + [1]*5 + [0]*0\r\n",
    "    X, y, amounts, gids = [],[],[],[]\r\n",
    "    for row in X_val.groupby('gid').apply(fun2, s=s):\r\n",
    "        seq, res, amount, gid, _, _, _ = row\r\n",
    "        X.append(seq)\r\n",
    "        y.append(y)\r\n",
    "        amounts.append(amount)\r\n",
    "        gids.append(gid)\r\n",
    "        break\r\n",
    "        # print(seq, res, amount, gid)    \r\n",
    "    X = np.vstack(X)\r\n",
    "    y_true = np.array(y)\r\n",
    "    # print(X.shape, y_true.shape)\r\n",
    "    y_pred = model.predict(X)\r\n",
    "    gids = np.array(gids)\r\n",
    "    amounts = np.array(amounts)\r\n",
    "    return X, y_true, y_pred, gids, amounts\r\n",
    "\r\n",
    "\r\n",
    "# fun2(X_val.sample(14, replace=False),[2]*5 + [1]*5 + [0]*0)\r\n",
    "model, _ = fun3(X_test)\r\n",
    "X, y_ture, y_pred, gids, amounts = fun4(X_val, model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[9, 9, 8, 7, 6, 6, 5, 4, 2]]),\n",
       " array([[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[list([[...]])]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],\n",
       "       dtype=object),\n",
       " array([0.08874654]),\n",
       " array(['19001'], dtype='<U5'),\n",
       " array([2304]))"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X, y_ture, y_pred, gids, amounts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'00001'"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'%.5d' % 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# euro_data.shape, euro_data.merge(zcsf_data.drop('gid',axis=1), on=['match_time','home'], how=\"outer\", indicator=True).query('_merge==\"left_only\"').shape, zcsf_data.shape\r\n",
    "# X_val = euro_data.merge(zcsf_data,on=['match_time','home'],how='inner')\r\n",
    "# X_val = X_val[X_val.result_type != -1]\r\n",
    "\r\n",
    "# zcsf_data.head()\r\n",
    "# pred_val = lgb_model.predict_proba(X_val.loc[:,feat_cols_euro], num_iteration=lgb_model.best_iteration_)\r\n",
    "\r\n",
    "# lgb_model.predict(X_val.loc[:,feat_cols_euro], num_iteration=lgb_model.best_iteration_)\r\n",
    "def eval(x,s):\r\n",
    "\r\n",
    "    x_sort = x.sort_values('probmax',ascending=False).iloc[:14]\r\n",
    "    candidates = []\r\n",
    "\r\n",
    "    for idx,pos in enumerate(s):\r\n",
    "        if pos == 0:\r\n",
    "            candidates += list(zip(*x_sort.iloc[idx:idx+1,:].loc[:,['argmax']].T.values))\r\n",
    "        elif pos == 1:\r\n",
    "            candidates += list(zip(*x_sort.iloc[idx:idx+1,:].loc[:,['argmax','argmid']].T.values))\r\n",
    "        elif pos == 2:\r\n",
    "            candidates += list(zip(*x_sort.iloc[idx:idx+1,:].loc[:,['argmax','argmid','argmin']].T.values))\r\n",
    "\r\n",
    "    answer = list(zip(*x_sort.iloc[:9,:].loc[:,['result_type']].T.values))\r\n",
    "    answer = list(product(*answer))\r\n",
    "    \r\n",
    "    candidates = list(product(*(candidates))) # list(product(*a)) + list(product(*b)) +\r\n",
    "    # print(s, pos, idx, len(candidates)) \r\n",
    "    # print(x.gid.max(), len(candidates), answer)\r\n",
    "    # if answer[0] in candidates:\r\n",
    "    #     print(x_sort.home.iloc[:9].values, s, x_sort.result_type.iloc[:9].values)\r\n",
    "    return pd.DataFrame(data={'gid':[x.gid.max()], \\\r\n",
    "                              'win':[answer[0] in candidates], \\\r\n",
    "                              'bet_amount':[len(candidates) * 2], \\\r\n",
    "                              'prob_9':[x_sort.head(9).probmax.mean()], \\\r\n",
    "                              'prob_all':[x.probmax.mean()], \\\r\n",
    "                              })\r\n",
    "\r\n",
    "# print(X_val.groupby('gid',as_index=False).apply(fun))\r\n",
    "\r\n",
    "lottery_95 = lottery[lottery.first_price_9 < lottery.first_price_9.quantile(0.95)]\r\n",
    "\r\n",
    "best_s = []\r\n",
    "reports = []\r\n",
    "# for idx, s in enumerate(list(combinations_with_replacement([0,1,2], 9))):\r\n",
    "for idx, s in enumerate(\\\r\n",
    "                set(list(combinations_with_replacement([2,1,0], 9)) + \\\r\n",
    "                list(combinations_with_replacement([0,1,2], 9)))):\r\n",
    "    # if sum(s) < 6:\r\n",
    "    #     continue\r\n",
    "    report = pd.merge(X_val.groupby('gid',as_index=False).apply(eval,s=s), lottery_95, on='gid')\r\n",
    "    report['rate_return'] = report.apply(lambda x: x['win'] *x['first_price_9'] / x['bet_amount'] -1, axis=1)# rate of return\r\n",
    "    report['sid'] = idx\r\n",
    "    reports.append(report)\r\n",
    "    # if (report.rate_return.mean() > 0.1) and (report.win.mean() > 0.1):\r\n",
    "    if report.rolling(window=10).mean().rate_return.quantile(0.7) > 0:\r\n",
    "        print(idx, s, report.win.mean(), report.win.sum(), \\\r\n",
    "              report.rate_return.mean(), report.bet_amount.max() )\r\n",
    "        print(report.groupby('win').agg({'prob_9':'mean', 'prob_all':'mean'}))\r\n",
    "        # print(s)\r\n",
    "        # print(report.groupby(pd.qcut(report.gid.map(int), 5, precision=0)).agg({'win':['mean','count'],'rate_return':'mean','bet_amount':'max'}))\r\n",
    "        # if report.win.mean() > 0.1:\r\n",
    "        #     best_s.append((s,report.win.mean()))\r\n",
    "\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  2%|▏         | 3/129 [00:07<05:16,  2.51s/it]\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-11-a2cbe4171e6d>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m     50\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mreports\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     51\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 52\u001b[0;31m \u001b[0mreports_2019\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcal_report\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX_val\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mX_val\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatch_time\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0myear\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m2019\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcopy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlottery_95\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     53\u001b[0m \u001b[0mreports_2020\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcal_report\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX_val\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mX_val\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmatch_time\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0myear\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m2020\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcopy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlottery_95\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     54\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m<ipython-input-11-a2cbe4171e6d>\u001b[0m in \u001b[0;36mcal_report\u001b[0;34m(X_val, lottery_95)\u001b[0m\n\u001b[1;32m     39\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     40\u001b[0m     \u001b[0;32mfor\u001b[0m \u001b[0midx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ms\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstrategies\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m,\u001b[0m\u001b[0mtotal\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstrategies\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 41\u001b[0;31m         \u001b[0mreport\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmerge\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX_val\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgroupby\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'gid'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mas_index\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0meval2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlottery_95\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mon\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'gid'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     42\u001b[0m         \u001b[0mreport\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'rate_profit'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mreport\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'win'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'first_price_9'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'bet_amount'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;31m# rate of return\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     43\u001b[0m         \u001b[0mreport\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'profit'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mreport\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'win'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'first_price_9'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/groupby/groupby.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, func, *args, **kwargs)\u001b[0m\n\u001b[1;32m    857\u001b[0m         \u001b[0;32mwith\u001b[0m \u001b[0moption_context\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"mode.chained_assignment\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    858\u001b[0m             \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 859\u001b[0;31m                 \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_python_apply_general\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_selected_obj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    860\u001b[0m             \u001b[0;32mexcept\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    861\u001b[0m                 \u001b[0;31m# gh-20949\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/groupby/groupby.py\u001b[0m in \u001b[0;36m_python_apply_general\u001b[0;34m(self, f, data)\u001b[0m\n\u001b[1;32m    890\u001b[0m             \u001b[0mdata\u001b[0m \u001b[0mafter\u001b[0m \u001b[0mapplying\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    891\u001b[0m         \"\"\"\n\u001b[0;32m--> 892\u001b[0;31m         \u001b[0mkeys\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmutated\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgrouper\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    893\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    894\u001b[0m         return self._wrap_applied_output(\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/groupby/ops.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, f, data, axis)\u001b[0m\n\u001b[1;32m    218\u001b[0m             \u001b[0;31m# group might be modified\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    219\u001b[0m             \u001b[0mgroup_axes\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgroup\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maxes\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 220\u001b[0;31m             \u001b[0mres\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgroup\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    221\u001b[0m             \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0m_is_indexed_like\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgroup_axes\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    222\u001b[0m                 \u001b[0mmutated\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/groupby/groupby.py\u001b[0m in \u001b[0;36mf\u001b[0;34m(g)\u001b[0m\n\u001b[1;32m    841\u001b[0m                 \u001b[0;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    842\u001b[0m                     \u001b[0;32mwith\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0merrstate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"ignore\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 843\u001b[0;31m                         \u001b[0;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    844\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    845\u001b[0m             \u001b[0;32melif\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnanops\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"nan\"\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m<ipython-input-11-a2cbe4171e6d>\u001b[0m in \u001b[0;36meval2\u001b[0;34m(x, s)\u001b[0m\n\u001b[1;32m     22\u001b[0m                               \u001b[0;34m'bet_amount'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcandidates\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     23\u001b[0m                               \u001b[0;34m'prob_9'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mx_sort\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhead\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m9\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprobmax\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 24\u001b[0;31m                               \u001b[0;34m'prob_all'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprobmax\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     25\u001b[0m                               })\n\u001b[1;32m     26\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, data, index, columns, dtype, copy)\u001b[0m\n\u001b[1;32m    466\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    467\u001b[0m         \u001b[0;32melif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdict\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 468\u001b[0;31m             \u001b[0mmgr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0minit_dict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolumns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    469\u001b[0m         \u001b[0;32melif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMaskedArray\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    470\u001b[0m             \u001b[0;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmrecords\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mmrecords\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/internals/construction.py\u001b[0m in \u001b[0;36minit_dict\u001b[0;34m(data, index, columns, dtype)\u001b[0m\n\u001b[1;32m    281\u001b[0m             \u001b[0marr\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mis_datetime64tz_dtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marr\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0marr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcopy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0marr\u001b[0m \u001b[0;32min\u001b[0m \u001b[0marrays\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    282\u001b[0m         ]\n\u001b[0;32m--> 283\u001b[0;31m     \u001b[0;32mreturn\u001b[0m \u001b[0marrays_to_mgr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata_names\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcolumns\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    284\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    285\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/internals/construction.py\u001b[0m in \u001b[0;36marrays_to_mgr\u001b[0;34m(arrays, arr_names, index, columns, dtype, verify_integrity)\u001b[0m\n\u001b[1;32m     81\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     82\u001b[0m         \u001b[0;31m# don't force copy because getting jammed in an ndarray anyway\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 83\u001b[0;31m         \u001b[0marrays\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_homogenize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marrays\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     84\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     85\u001b[0m         \u001b[0mcolumns\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mensure_index\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcolumns\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/internals/construction.py\u001b[0m in \u001b[0;36m_homogenize\u001b[0;34m(data, index, dtype)\u001b[0m\n\u001b[1;32m    350\u001b[0m                 \u001b[0mval\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlib\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfast_multiget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mval\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moindex\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_values\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdefault\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnan\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    351\u001b[0m             val = sanitize_array(\n\u001b[0;32m--> 352\u001b[0;31m                 \u001b[0mval\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mraise_cast_failure\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    353\u001b[0m             )\n\u001b[1;32m    354\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/construction.py\u001b[0m in \u001b[0;36msanitize_array\u001b[0;34m(data, index, dtype, copy, raise_cast_failure)\u001b[0m\n\u001b[1;32m    447\u001b[0m             \u001b[0msubarr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_try_cast\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcopy\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mraise_cast_failure\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    448\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 449\u001b[0;31m             \u001b[0msubarr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmaybe_convert_platform\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    450\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    451\u001b[0m         \u001b[0msubarr\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmaybe_cast_to_datetime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msubarr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/dtypes/cast.py\u001b[0m in \u001b[0;36mmaybe_convert_platform\u001b[0;34m(values)\u001b[0m\n\u001b[1;32m     89\u001b[0m     \u001b[0;34m\"\"\" try to do platform conversion, allow ndarray or list here \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     90\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mlist\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 91\u001b[0;31m         \u001b[0mvalues\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mconstruct_1d_object_array_from_listlike\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     92\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0mgetattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"dtype\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mobject_\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     93\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mhasattr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"_values\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/dtypes/cast.py\u001b[0m in \u001b[0;36mconstruct_1d_object_array_from_listlike\u001b[0;34m(values)\u001b[0m\n\u001b[1;32m   1589\u001b[0m     \u001b[0;31m# making a 1D array that contains list-likes is a bit tricky:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1590\u001b[0m     \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mempty\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"object\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1591\u001b[0;31m     \u001b[0mresult\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalues\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   1592\u001b[0m     \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   1593\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "def eval2(x,s):\r\n",
    "\r\n",
    "    x_sort = x.sort_values('probmax',ascending=False).iloc[:14]\r\n",
    "    candidates = []\r\n",
    "    for idx in range(9):\r\n",
    "        # print(s, x_sort.prob_cut)\r\n",
    "        pos = s[x_sort.bins.iloc[idx]]\r\n",
    "        if pos == 0:\r\n",
    "            candidates += list(zip(*x_sort.iloc[idx:idx+1,:].loc[:,['argmax']].T.values))\r\n",
    "        elif pos == 1:\r\n",
    "            candidates += list(zip(*x_sort.iloc[idx:idx+1,:].loc[:,['argmax','argmid']].T.values))\r\n",
    "        elif pos == 2:\r\n",
    "            candidates += list(zip(*x_sort.iloc[idx:idx+1,:].loc[:,['argmax','argmid','argmin']].T.values))\r\n",
    "\r\n",
    "    answer = list(zip(*x_sort.iloc[:9,:].loc[:,['result_type']].T.values))\r\n",
    "    answer = list(product(*answer))\r\n",
    "    \r\n",
    "    candidates = list(product(*(candidates))) \r\n",
    "  \r\n",
    "    return pd.DataFrame(data={'gid':[x.gid.max()], \\\r\n",
    "                              'win':[answer[0] in candidates], \\\r\n",
    "                              'bet_amount':[len(candidates) * 2], \\\r\n",
    "                              'prob_9':[x_sort.head(9).probmax.mean()], \\\r\n",
    "                              'prob_all':[x.probmax.mean()], \\\r\n",
    "                              })\r\n",
    "\r\n",
    "# X_val['prob_cut'] = pd.qcut(X_val.probmax, 10, labels=False)\r\n",
    "lottery_95 = lottery[lottery.first_price_9 < lottery.first_price_9.quantile(0.95)]\r\n",
    "\r\n",
    "\r\n",
    "# for idx, s in enumerate(list(combinations_with_replacement([0,1,2], 9))):\r\n",
    "\r\n",
    "def cal_report(X_val, lottery_95):\r\n",
    "    reports = []\r\n",
    "    \r\n",
    "    strategies = set(list(combinations_with_replacement([0,1,2], 10)) + \\\r\n",
    "                     list(combinations_with_replacement([2,1,0], 10))\r\n",
    "                            )\r\n",
    "\r\n",
    "    for idx, s in tqdm(enumerate(strategies) ,total=len(strategies)):\r\n",
    "        report = pd.merge(X_val.groupby('gid',as_index=False).apply(eval2,s=s), lottery_95, on='gid')\r\n",
    "        report['rate_profit'] = report.apply(lambda x: x['win'] *x['first_price_9'] / x['bet_amount'] -1, axis=1)# rate of return\r\n",
    "        report['profit'] = report.apply(lambda x: x['win'] *x['first_price_9'], axis=1)\r\n",
    "        report['sid'] = idx\r\n",
    "        reports.append(report)\r\n",
    "        # if (report.rate_profit.mean() > -0.5) and (report.win.mean() > 0.0):\r\n",
    "        #     print(idx, s, report.win.mean(), \\\r\n",
    "        #         report.rate_profit.mean(), report.bet_amount.mean() )\r\n",
    "    reports = pd.concat(reports,axis=0)\r\n",
    "    return reports\r\n",
    "\r\n",
    "reports_2019 = cal_report(X_val[X_val.match_time.dt.year == 2019].copy(), lottery_95)\r\n",
    "reports_2020 = cal_report(X_val[X_val.match_time.dt.year == 2020].copy(), lottery_95)\r\n",
    "\r\n",
    "reports_2021 = cal_report(X_val[X_val.match_time.dt.year == 2021].copy(), lottery_95)\r\n",
    "\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "No axis named probmax for object type Series",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/generic.py\u001b[0m in \u001b[0;36m_get_axis_number\u001b[0;34m(cls, axis)\u001b[0m\n\u001b[1;32m    367\u001b[0m         \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 368\u001b[0;31m             \u001b[0;32mreturn\u001b[0m \u001b[0mcls\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_AXIS_TO_AXIS_NUMBER\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    369\u001b[0m         \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mKeyError\u001b[0m: 'probmax'",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-18-596a33b5ca82>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mX_val\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0meval2\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0;36m9\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0;31m# X_val.head().T\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/frame.py\u001b[0m in \u001b[0;36mapply\u001b[0;34m(self, func, axis, raw, result_type, args, **kwds)\u001b[0m\n\u001b[1;32m   7550\u001b[0m             \u001b[0mkwds\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mkwds\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   7551\u001b[0m         )\n\u001b[0;32m-> 7552\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_result\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   7553\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   7554\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mapplymap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0;34m\"DataFrame\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/apply.py\u001b[0m in \u001b[0;36mget_result\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    183\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply_raw\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    184\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 185\u001b[0;31m         \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply_standard\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    186\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    187\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mapply_empty_result\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/apply.py\u001b[0m in \u001b[0;36mapply_standard\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    274\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    275\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mapply_standard\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 276\u001b[0;31m         \u001b[0mresults\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mres_index\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply_series_generator\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    277\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    278\u001b[0m         \u001b[0;31m# wrap results\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/apply.py\u001b[0m in \u001b[0;36mapply_series_generator\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    303\u001b[0m                 \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mv\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mseries_gen\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    304\u001b[0m                     \u001b[0;31m# ignore SettingWithCopy here in case the user mutates\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 305\u001b[0;31m                     \u001b[0mresults\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    306\u001b[0m                     \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresults\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mABCSeries\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    307\u001b[0m                         \u001b[0;31m# If we have a view on v, we need to make a copy because\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/apply.py\u001b[0m in \u001b[0;36mf\u001b[0;34m(x)\u001b[0m\n\u001b[1;32m    112\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    113\u001b[0m             \u001b[0;32mdef\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 114\u001b[0;31m                 \u001b[0;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwds\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    115\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    116\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m<ipython-input-11-a2cbe4171e6d>\u001b[0m in \u001b[0;36meval2\u001b[0;34m(x, s)\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0meval2\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m     \u001b[0mx_sort\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msort_values\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'probmax'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mascending\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0miloc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m14\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      4\u001b[0m     \u001b[0mcandidates\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m     \u001b[0;32mfor\u001b[0m \u001b[0midx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m9\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/series.py\u001b[0m in \u001b[0;36msort_values\u001b[0;34m(self, axis, ascending, inplace, kind, na_position, ignore_index, key)\u001b[0m\n\u001b[1;32m   3242\u001b[0m         \u001b[0minplace\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalidate_bool_kwarg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minplace\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"inplace\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   3243\u001b[0m         \u001b[0;31m# Validate the axis parameter\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3244\u001b[0;31m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_axis_number\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m   3245\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m   3246\u001b[0m         \u001b[0;31m# GH 5856/5853\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/generic.py\u001b[0m in \u001b[0;36m_get_axis_number\u001b[0;34m(cls, axis)\u001b[0m\n\u001b[1;32m    368\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0mcls\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_AXIS_TO_AXIS_NUMBER\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    369\u001b[0m         \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 370\u001b[0;31m             \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"No axis named {axis} for object type {cls.__name__}\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    371\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    372\u001b[0m     \u001b[0;34m@\u001b[0m\u001b[0mclassmethod\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mValueError\u001b[0m: No axis named probmax for object type Series"
     ]
    }
   ],
   "source": [
    "X_val.apply(eval2,s=[1]*9, axis=0)\r\n",
    "# X_val.head().T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/reshape/merge.py:643: UserWarning: merging between different levels can give an unintended result (1 levels on the left,2 on the right)\n",
      "  warnings.warn(msg, UserWarning)\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/generic.py:3889: PerformanceWarning: dropping on a non-lexsorted multi-index without a level parameter may impact performance.\n",
      "  obj = obj._drop_axis(labels, axis, level=level, errors=errors)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe thead tr:last-of-type th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th colspan=\"2\" halign=\"left\">bet_amount</th>\n",
       "      <th>first_price_9</th>\n",
       "      <th colspan=\"2\" halign=\"left\">gid</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th></th>\n",
       "      <th>mean</th>\n",
       "      <th>sum</th>\n",
       "      <th>sum</th>\n",
       "      <th>nunique</th>\n",
       "      <th>count</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>win</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>False</th>\n",
       "      <td>63.922747</td>\n",
       "      <td>119152</td>\n",
       "      <td>22486160</td>\n",
       "      <td>160</td>\n",
       "      <td>1864</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>True</th>\n",
       "      <td>179.276836</td>\n",
       "      <td>31732</td>\n",
       "      <td>203358</td>\n",
       "      <td>45</td>\n",
       "      <td>177</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       bet_amount         first_price_9     gid      \n",
       "             mean     sum           sum nunique count\n",
       "win                                                  \n",
       "False   63.922747  119152      22486160     160  1864\n",
       "True   179.276836   31732        203358      45   177"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# reports = pd.concat(reports,axis=0)\r\n",
    "# reports[reports.sid == 9].rolling(window=10).mean().win.plot()\r\n",
    "# reports[reports.sid == 9].describe()\r\n",
    "r = reports_2021.groupby(['sid','bet_amount']).agg({'win':['count','mean'],'rate_profit':'mean'})\r\n",
    "s_pool = r[r[('rate_profit','mean')] > 0.5].reset_index() # .sort_values(('rate_return','mean'))\r\n",
    "s_pool = s_pool[(s_pool.bet_amount < 1000) & (s_pool.bet_amount > 1)]\r\n",
    "# r.sum()\r\n",
    "reports_2019.merge(s_pool, on=['sid','bet_amount']).groupby(['win']).agg({'bet_amount':['mean','sum'],'first_price_9':'sum','gid':['nunique','count']}) # .groupby('win').sum() # .rolling(window=10).sum().plot() # .gid.nunique(), reports.gid.nunique()\r\n",
    "# s_pool.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/reshape/merge.py:643: UserWarning: merging between different levels can give an unintended result (1 levels on the left,2 on the right)\n",
      "  warnings.warn(msg, UserWarning)\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/generic.py:3889: PerformanceWarning: dropping on a non-lexsorted multi-index without a level parameter may impact performance.\n",
      "  obj = obj._drop_axis(labels, axis, level=level, errors=errors)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f9c95f22550>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZMAAAEKCAYAAADXdbjqAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzt3XmcXFWd///Xp/ek00k6+54OiyEkhK1JIotsssgIEYdRFBEU5eGC4/Idv+BXBwEdRYcRUJGvfAcExkFQRiBgFAHhJ8iahGA2lgAh6WwdOp2l9+6qz++PczqpDt1Zuqu7qrvez8ejHlV17rn3nttLfeqe1dwdERGRnsjLdAFERKT/UzAREZEeUzAREZEeUzAREZEeUzAREZEeUzAREZEeUzAREZEeUzAREZEeUzAREZEeK8h0AfrKqFGjvKKiItPFEBHpVxYvXvyuu4/eV76cCSYVFRUsWrQo08UQEelXzOyd/cmnai4REekxBRMREekxBRMREemxnGkz6UxraytVVVU0NTVluig5p6SkhEmTJlFYWJjpoohIGuR0MKmqqqKsrIyKigrMLNPFyRnuTk1NDVVVVUybNi3TxRGRNMjpaq6mpiZGjhypQNLHzIyRI0fqjlBkAMnpYAIokGSIfu4iA0tOV3OJiPRHTa0JHl2xiabWBEkHd0i64+44kEg6Ta1JGlsT4M7pM8Zy5OThvVomBZN+7tVXX+XCCy/EzLj//vu5+OKLefbZZ1mzZg3PPvssn/zkJzNdRBFJs8dWbuar9y7dr7xmMGZoiYKJQCKRID8/v9NtDz74IBdccAHf+c53AHj22WcBWLNmDffcc4+CicgAtGFbIwCPf+NkSovzyTPDDAwjz0I18qDCfEoK8/qsSjnn20wybc2aNRx22GFcdNFFzJgxgwsuuICGhgYqKiq48sorOeaYY/jd737H0qVLmTdvHrNnz+b888+ntraWhQsXctNNN3Hrrbdy6qmnAjBkyBAArrrqKp5++mmOOuoobrzxxkxeooik2ZadzQwqzOfg0aWMHzaIsUNLGFNWwuiyYkYOKWZEaRGDivL7tG1SdybRtQ+vYOWGHWk95uEThvLdc2fuM99rr73G7bffzgknnMBnP/tZfvGLXwAwcuRIlixZAsDs2bP52c9+xsknn8zVV1/Ntddey0033cQXvvAFhgwZwr/8y790OOb111/PDTfcwCOPPJLWaxKRzKve2cyYocVZ1ZFFdyZZYPLkyZxwwgkAfOpTn+KZZ54B4OMf/zgA27dvZ9u2bZx88skAXHLJJfz1r3/NTGFFJOOqdzYxpqw408XoQHcm0f7cQfSWPb9dtL8vLS3NRHFEJMtt2dnM9HFlmS5GB/u8MzGzO8ys2syWp6SNMLPHzOyN+Fwe083Mfmpmq83s72Z2TMo+l8T8b5jZJSnpx5rZsrjPTy1+knbnHP3V2rVree655wC45557OPHEEztsHzZsGOXl5Tz99NMA/Nd//deuu5SulJWVsXPnzt4psIhkVPXOZsaUlWS6GB3sTzXXncDZe6RdBTzh7ocCT8T3AB8CDo2Py4FbIQQG4LvAXGAO8N324BDzfD5lv7O7c47+bPr06dxyyy3MmDGD2tpavvjFL74nz1133cU3v/lNZs+ezdKlS7n66qv3eszZs2eTn5/PkUceqQZ4kQGkqTXBzqY2Rve3ai53/6uZVeyRPB84Jb6+C3gKuDKm3+3uDjxvZsPNbHzM+5i7bwUws8eAs83sKWCouz8f0+8GPgL88UDP4e4bD+zSs0dBQQG//vWvO6StWbOmw/ujjjqK559//j37XnPNNR3e19XVAVBYWMhf/vKXtJZTRDKvekczQNYFk+42wI9N+fDeBIyNrycC61LyVcW0vaVXdZLenXOIiAx4W+rCnHYDrgHe3d3MPB2FSfc5zOxyQlUYU6ZMSXu50qGiooLly5fvO6OI5DR35/FV1dz30lqAftlm0pnNsfqK+Fwd09cDk1PyTYppe0uf1El6d87xHu5+m7tXunvl6NGjD+gCRUSyyf2Lq/j83Yt44e2tnDJ9NAeNzq7ent0NJguA9h5ZlwAPpaR/Ova4mgdsj1VVjwJnmll5bHg/E3g0btthZvNiL65P73GsAzmHiMiA9czqdxk7tJgl/3oGd35mDiWFnU+xlCn7rOYys98QGsJHmVkVoVfW9cBvzewy4B3gYzH7QuAcYDXQAHwGwN23mtn3gJdivuvaG+OBLxF6jA0iNLz/MaYf0DlERAayJWtrOWZKOYX52TnWfH96c32ii02nd5LXgS93cZw7gDs6SV8EzOokveZAzyEiMhBt2dnMuq2NXDxvaqaL0qXsDHEiIrLLkrW1ABw9pXwfOTNHwSTD1qxZw6xZ77kx69Kdd97Jhg0berFE6bN06VIWLlyY6WKI9FtVtQ088HIV//aHVYwaUsQRE4dlukhd0txc/cydd97JrFmzmDBhQqaLsk9Lly5l0aJFnHPOOZkuikhWSyadH/3pVRa8soHWRJK2pJNIODub2wAoLcrn15+bm3WN7qkUTNr98SrYtCy9xxx3BHzo+n1ma2tr46KLLmLJkiXMnDmTu+++m1WrVvGNb3yDuro6Ro0axZ133snf/vY3Fi1axEUXXcSgQYN47rnnGDRo0HuOd9111/Hwww/T2NjI8ccfzy9/+UvMjFNOOYWjjz6ap59+mvr6eu6++25++MMfsmzZMj7+8Y/z/e9/H4Cf/OQn3HFHaN763Oc+x9e+9jXWrFnDhz/84V1jYm644Qbq6uq45pprOOWUU5g7dy5PPvkk27Zt4/bbb2fu3LlcffXVNDY28swzz/Ctb31r1yzIIrLbT594g1ueXE1zW5IPzhjDmKElFOQZ+XnGqCHFfHDGWCYML6GspDDTRd0rBZMssOd6JrfccgsPPPAADz30EKNHj+a+++7j29/+NnfccQc///nPueGGG6isrOzyeFdcccWuubsuvvhiHnnkEc4991wAioqKWLRoETfffDPz589n8eLFjBgxgoMPPpivf/3rrFmzhl/96le88MILuDtz587l5JNPprx873W1bW1tvPjiiyxcuJBrr72Wxx9/nOuuu45Fixbx85//PH0/LJEB5uk3tjC6rJhvnjWd+Uf138k8FEza7ccdRG/Zcz2TH/zgByxfvpwzzjgDCMv2jh8/fr+P9+STT/LjH/+YhoYGtm7dysyZM3cFk/POOw+AI444gpkzZ+467kEHHcS6det45plnOP/883dNf//Rj36Up59+etd+XfnoRz8KwLHHHvueecVEpGtVtY0cf/Cofh1IQMEkK+y5nklZWRkzZ87cNS39gWhqauJLX/oSixYtYvLkyVxzzTU0NTXt2l5cHObzycvL2/W6/X1bW1uXxy0oKCCZTHY4T6r2Y+Xn5+/1OCKyW0tbkk07mpg84r3V1f2NenNlgT3XM5k3bx5btmzZldba2sqKFSuAfa9T0v4hP2rUKOrq6rj//vsPqCwnnXQSDz74IA0NDdTX1/PAAw9w0kknMXbsWKqrq6mpqaG5uXm/lgPWmioie7dhWyPuMKl8cKaL0mMKJllgz/VMvvKVr3D//fdz5ZVXcuSRR3LUUUfx7LPPAnDppZfyhS98gaOOOorGxsb3HGv48OF8/vOfZ9asWZx11lkcd9xxB1SWY445hksvvZQ5c+Ywd+5cPve5z3H00UdTWFjI1VdfzZw5czjjjDM47LDD9nmsU089lZUrV3LUUUdx3333HVA5RHJBVW34H55U3v/vTCwMKB/4KisrfdGiRR3SVq1axYwZMzJUItHPX3LdvS+u5arfL+OZK0/N2rsTM1vs7l33+Il0ZyIikiHrahsoyDPGDc2u6eS7Qw3w/dj555/P22+/3SHtRz/6EWeddVaGSiQiB6KqtpFxw0ooyNLJGw9EzgcTd39Pb6r+4oEHHsh0EbotV6pXRfZmy87mAXFXAjlezVVSUkJNTY0+2PqYu1NTU0NJycD4JxLprq31LZSXFmW6GGmR03cmkyZNoqqqii1btmS6KDmnpKSESZMm7TujyABW29DCkZOGZ7oYaZHTwaSwsJBp06ZluhgikoPcndr61gFzZ5LT1VwiIplS35KgJZFkRGl2T+C4vxRMREQyoLa+BYDywbozERGRbtoag8kIVXOJiEh3bW2IdyYKJiIi0l2q5hIRkR7bVc2lYCIiIt1V29BCfp5RVjIwRmgomIiIZEBtQyvlgwvJy+uf0zntaWCERBGRfuDeF9fy+KpqwFm2fvuAaS8BBRMRkT7h7vzHY6+TSDrjhpYwakgx5xwxPtPFShsFExGRPrBxexNbdjZz7XkzueT4ikwXJ+3UZiIi0gdeWbcNgCMnD4yJHfekYCIi0geWrttGUX4eM8aXZboovaJHwcTMvm5mK8xsuZn9xsxKzGyamb1gZqvN7D4zK4p5i+P71XF7RcpxvhXTXzOzs1LSz45pq83sqpT0Ts8hIpJtvnbvyxz/wye467k1HD5hKMUF+ZkuUq/odjAxs4nAPwOV7j4LyAcuBH4E3OjuhwC1wGVxl8uA2ph+Y8yHmR0e95sJnA38wszyzSwfuAX4EHA48ImYl72cQ0Qka6zauIMHl25g6shSzp09ga+f8b5MF6nX9LQBvgAYZGatwGBgI3Aa8Mm4/S7gGuBWYH58DXA/8HML6+XOB+5192bgbTNbDcyJ+Va7+1sAZnYvMN/MVu3lHCIiGbX4nVo2bm8E4JFXNlJUkMetnzqG4QOoG3Bnuh1M3H29md0ArAUagT8Di4Ft7t4Ws1UBE+PricC6uG+bmW0HRsb051MOnbrPuj3S58Z9ujpHB2Z2OXA5wJQpU7p3oSKS09yd1oTT2Jqgtr6FrQ0tJJNOU2uS59+qYXV1HS2JJADbG1tZ/E5th/0vOHbSgA8k0INgYmblhLuKacA24HeEaqqs4e63AbcBVFZWaqF3kRzn7mzZ2UzCHXfwmObevh2c3dueWf0u1y9cRX1LotPjFeQZU0cOZnBR+CjNM/jfZ0/njBljd+WZOrK0l68qO/SkmuuDwNvuvgXAzH4PnAAMN7OCeOcwCVgf868HJgNVZlYADANqUtLbpe7TWXrNXs4hItKlW55czQ1/fv2A9jn+4JEcf/BISgrzGVFaRPngIgryjXwzZk0axtCSgbFSYk/1JJisBeaZ2WBCNdfpwCLgSeAC4F7gEuChmH9BfP9c3P4Xd3czWwDcY2Y/ASYAhwIvAgYcambTCMHiQuCTcZ+uziEi0qWX125jUvkgrjj1EMzAiPNiWfjAMbP4HB5Digs57bAx5A+Q+bN6U0/aTF4ws/uBJUAb8DKhSukPwL1m9v2Ydnvc5Xbgv2ID+1ZCcMDdV5jZb4GV8ThfdvcEgJldATxK6Cl2h7uviMe6sotziIh06c0tdRw5eTgXzlEbarqZe240JVRWVvqiRYsyXQwRyZDmtgQz/vVPXHHaoXxjAHfRTTczW+zulfvKpxHwIpIT1rzbQNLh4NG50SDe1xRMRCQnvLmlDoCDRw/JcEkGJs0aLCL9XjIZxoE4sGl7EzV1zUAY97G9sRWAJ1ZVA3CQ7kx6hYKJiPR7l975En99fcs+8514yKhdY0IkvfRTFZF+bcvOZp5+YwtnHj6WyopyRpQWM35YCQYMLi5gZGkYfV5WUpATI9EzRcFERPq1J1+txh2++sFDmTlhWKaLk7MUTEQkbdydpENdUxvVO5u6fZyWRJLV1XU0tiRoTTqvbdpBfXPnU5osXbeN8cNKOHz80G6fT3pOwURE9ou7U9fcRjIJCXcSSactmeTHf3qNBa9sIJHsvTFrZcUFlJd2XUV12YnTCJOQS6YomIgMcG2JJG3JMHlh0p3kfg5UdmDNu/XUNrTS3JrgxsffYNXGHZ3m/eTcKYwaUkyeQZ4ZgwrzGTushO7OQpJnxkGjSxk2qBDDGF1WrClNspyCiUg/8dybNVz78Arejd1e9yWRdOpbErS0JdNy/hGlRXzzrOmUFOaTb5CfZ+TlGdPHllFZMSIt55D+S8FEpJ/4wcJVbGto5YzDx+3XN34zKC0uoLSogIJ8I8+MvDi54f7WCI0bVsL4YYMAOGT0EIYN1gy50jkFE5E02Li9kdr61l1rYUCoUuqwZgZxvYz9eZ2ypkbSnc3bm1i2fjvXzZ/Jp99fkaGrFOmagonIAXJ3lq7bRmNcMOnlddu44c+v0dtzppYVF3D+0Z0uKiqScQomIp1wdxa/U8vLa7e9p8F60Tu1PLZyc4e0s2aOjR/0FtfJCGtj5MV1MSwumJG6Zkae7c5LSvWTAXl5u9fVaD/muKEllGkhJslSCiYie3h10w6+9ftlvLx2W6fbC/ONb541ncqp5QAUF+Yze+Iw8tTbSHKYgolIir+tfpfP3vkSZSUF/PCjR3DWzHGUFHacXDs/zyguyM9QCUWyk4KJSJRMOtc9vJLxw0r43ReOZ3RZcaaLJNJvKJjIgFHf3Ma/P/raroF1u1o6vP0pvHDvkEz7aqPNbUle27yTmy88SoFE5AApmEivqd7RxBNxEr5Udc2trN0aVr3b0/bGVl58eytNrXEepj261kLHrrMxC3iY4sPdOXZqeWjcJjZgtzeAp4yv2PXM7naO0mK48LjJfHj2hHRcvkhOUTCRXvPdBSv44/JNnW4bPriQgrz3LvRZlG+ccPBIhg8u6vCBv7uH1O7eUHFjh+2nHjaG4zQaW6TPKZhIr9i4vZE/r9zMpcdX8MVTDu6wrbggT+tKiAwwCibSqZa2JI0tiQ7tDO3VTM1tCW567A1eXldLS1uSuuYELW0dpwdvTYQJBT97wjTGDi3p49KLSF9TMBEAnn+rhuqdYQLBrXXN3PTEG2xraO0yf36ecer00QwqKmBIcQHFBe+tsjpsXBlTRg7utTKLSPZQMBE2bW/iE//v+Q4N5UdOHs4/nzYhpd0iPseEY6eWM2uiVrUTkUDBRFiythZ3+L+fOoZDxpSRZzB1ZKnWjxCR/aZgIixdt42igjxOO2wsRZ1UV4mI7Is+OYSX19Yya8JQBRIR6TbdmeSYmrpmbnz8dXY0tu1Ke6VqOxfPm5rBUolIf9ejYGJmw4H/BGYReo5+FngNuA+oANYAH3P3WgsttzcD5wANwKXuviQe5xLgO/Gw33f3u2L6scCdwCBgIfBVd3czG9HZOXpyLQPF9sZWVmzYTjL53ulDdjS18rMnVvP2u/VMLB+0a5+pIwZzzhHjMlFcERkgenpncjPwJ3e/wMyKgMHA/wGecPfrzewq4CrgSuBDwKHxMRe4FZgbA8N3gUpCQFpsZgticLgV+DzwAiGYnA38MR6zs3MMWP+zuIrbn3mbtmSStqTTlnASSQ/vEx7TkjS2JjqdpqTdiNIi7rj0OE48dFTfFV5EBrxuBxMzGwZ8ALgUwN1bgBYzmw+cErPdBTxF+KCfD9ztYVa9581suJmNj3kfc/et8biPAWeb2VPAUHd/PqbfDXyEEEy6OseAdc+La6ne2cxxFeXk5xkFeUZBfh4FedbhfVlJAcdOLaekMEyRvrtLLxTm5zFj/FAK89U2IiLp1ZM7k2nAFuBXZnYksBj4KjDW3TfGPJuAsfH1RGBdyv5VMW1v6VWdpLOXcwxIiaSzcsMOLpwzme+eOzPTxREReY+efEUtAI4BbnX3o4F6QnXTLvEupFdXxt7bOczscjNbZGaLtmzZ0pvF6FVvbqmjsTXBERokKCJZqifBpAqocvcX4vv7CcFlc6y+Ij5Xx+3rgckp+0+KaXtLn9RJOns5Rwfufpu7V7p75ejRo7t1kdlgWdV2AAUTEcla3Q4m7r4JWGdm02PS6cBKYAFwSUy7BHgovl4AfNqCecD2WFX1KHCmmZWbWTlwJvBo3LbDzObFnmCf3uNYnZ1jQFq2fjuDi/I5aPSQTBdFRKRTPe3N9RXgv2NPrreAzxAC1G/N7DLgHeBjMe9CQrfg1YSuwZ8BcPetZvY94KWY77r2xnjgS+zuGvzH+AC4votzDEhVtY1MGTFY05uISNbqUTBx96WELr17Or2TvA58uYvj3AHc0Un6IsIYlj3Tazo7x0BV39zGkGKNLxWR7KU+ov1AQ0sbpQomIpLFFEz6gTrdmYhIllMw6QfqmxMMLsrPdDFERLqkYNIP1DermktEspuCSZZzd+pbVM0lItlNwSTLNbUmSToMLlY1l4hkLwWTLFfXHNYd0Z2JiGQzBZMs19ASgklpkYKJiGQvBZMs135nUqpqLhHJYgomWa6+OQGg3lwiktUUTLJc/a47EwUTEcleCiZZrr5FDfAikv0UTLJc+52JRsCLSDZTMMlydbHNRHcmIpLNFEyy3O47EwUTEcleCiZZrr6ljaL8PIoK9KsSkeylT6gsFyZ5VHuJiGQ3BZMsV9+cULdgEcl6CiZZrKk1waqNOxhaUpjpooiI7JW+8vayVzftYGtdCwl3Nu9oprE1QTLpJJJO0p22pPP6pp3U1LfwTk09W+tbdu3blnQaWxPc8sljMngFIiL7pmDSi96pqeecm58m6XvPN2pIMROHlzB9XBnjhw3qsO39B4/krJnjerGUIiI9p2DSix58eQMO3H5JJWUlhYwuK2ZIcQH5eUa+GZYH+WYMLsrHzDJdXBGRblMw6QVPvlbNtoYWfv9yFXMqRnD6jLGZLpKISK9SMEmztTUNfOZXL+16/5XTDs1gaURE+oaCSZo1tIYR69eeN5PTZ4xh4vBB+9hDRKT/UzBJs7ZEaG0fO7SESeWDM1waEZG+oXEmaZb0EEzy89SgLiK5Q8EkzRKxH3CBgomI5BAFkzRrvzPJUzARkRzS42BiZvlm9rKZPRLfTzOzF8xstZndZ2ZFMb04vl8dt1ekHONbMf01MzsrJf3smLbazK5KSe/0HNkgkQzP+Ro3IiI5JB13Jl8FVqW8/xFwo7sfAtQCl8X0y4DamH5jzIeZHQ5cCMwEzgZ+EQNUPnAL8CHgcOATMe/ezpFx7dVcebrnE5Ec0qOPPDObBPwD8J/xvQGnAffHLHcBH4mv58f3xO2nx/zzgXvdvdnd3wZWA3PiY7W7v+XuLcC9wPx9nCPjdjXA685ERHJIT78/3wT8byBW7jAS2ObubfF9FTAxvp4IrAOI27fH/LvS99inq/S9nSPj2pLqzSUiuafbwcTMPgxUu/viNJYnrczscjNbZGaLtmzZ0ifnTCqYiEgO6smdyQnAeWa2hlAFdRpwMzDczNoHQ04C1sfX64HJAHH7MKAmNX2PfbpKr9nLOTpw99vcvdLdK0ePHt39Kz0ACQUTEclB3Q4m7v4td5/k7hWEBvS/uPtFwJPABTHbJcBD8fWC+J64/S/u7jH9wtjbaxpwKPAi8BJwaOy5VRTPsSDu09U5Mi7R3jVYbSYikkN6o8/RlcA3zGw1oX3j9ph+OzAypn8DuArA3VcAvwVWAn8CvuzuidgmcgXwKKG32G9j3r2dI+NUzSUiuSgtc3O5+1PAU/H1W4SeWHvmaQL+qYv9/w34t07SFwILO0nv9BzZIKHpVEQkB2k0RJrtGmeiai4RySEKJmmmBngRyUUKJmmmiR5FJBcpmKSZJnoUkVykYJJmmuhRRHKRgkma7Rpnop+siOQQfeSl2a5xJrozEZEcomCSZurNJSK5SMEkzXavZ6JgIiK5Q8EkzdrbTNQ1WERyiYJJmmkEvIjkIgWTNNNEjyKSixRM0iyhZXtFJAcpmKRZUg3wIpKDFEzSLOGuKi4RyTkKJmnWlnRVcYlIzlEwSbNkUncmIpIl3GHLa1Bf0+unSstKi7JbIqmeXCKSAe6wYQm8dAdsXwt11bBjAzTvgH/4Dzjuc716egWTNEu6o1giIn3CHTb9HZbeAysehLpNUDwMxhwGow6FipNg/Gw4+LReL4qCSZolVM0lIr2tpR4W/SoEkeoVkF8E7zsLDjoVjrgASob1eZEUTNJMvblEpFe4w1tPwd/vg7XPQe0amFgZqrBmfhQGj8ho8RRM0iyZdE2lIiLpsWMDvPqHUJX16kJoeBcGjYARB8H8W6DixEyXcBcFkzRrUzWXiByoRBs01kJDze5H9Up4/lZo2gYFg2DGuVBxAsy+EApLMl3i91AwSTN1DRaRDpJJ2LwMtq2FzSth5wZIJsCTULM6dN1t2tbJjgbTPgBnXw8jD4GCoj4v+oFQMEkztZmI5JhkEt55JlRJbX0LqleFANG4FVqboK0Rkm0xs0HpKLB8yMuHsvEw6x+hdDQMHhnaPUpHhddDJ2a8HeRAKJikWUIj4EUGpvoaePspqHkLtq0J7xtqYMf68ACwPCifBmNmhABROAgKSmDU+0Ja+VQYVJ7Jq+g1CiZplnTXJI8iA8HWt2H5/8CmZbC9KgwI9GTYNmQslI6BweUweQ5M/weYcDQMmxgCSA5SMEkz3ZmI9EMt9VC1KFRRtTXB5uWw7H7AQ8+pIePgA98MYznGHJ6zAWNvFEzSLJHU9PMiWW3Dy/Dmk2G6kbrNoZ1j0zLwxO48BSVw/Fdg3hdh6ITMlbUf6XYwMbPJwN3AWMCB29z9ZjMbAdwHVABrgI+5e62ZGXAzcA7QAFzq7kvisS4BvhMP/X13vyumHwvcCQwCFgJfdXfv6hzdvZZ0SiST5Gv6TJHs0NoYGsZ3rIft68OAv7eeDNuKh8KQMaGh+8Svw5R5MP4oKBoM+cWQr+/aB6InP6024H+5+xIzKwMWm9ljwKXAE+5+vZldBVwFXAl8CDg0PuYCtwJzY2D4LlBJCEqLzWxBDA63Ap8HXiAEk7OBP8ZjdnaOjEs45Ocpmoj0qdo1oZpq8/LQk2p7VQggDXvMljuoHM78Phz9qQHbEJ4p3Q4m7r4R2Bhf7zSzVcBEYD5wSsx2F/AU4YN+PnC3uzvwvJkNN7PxMe9j7r4VIAaks83sKWCouz8f0+8GPkIIJl2dI+OSSSdftVwiva9xWxjYV/Mm/OkqaKmDvAIYeSgMmwQTj4Ghk0I11bCJ4fXwyVBQnOmSD0hpuY8zswrgaMIdxNgYaAA2EarBIASadSm7VcW0vaVXdZLOXs6xZ7kuBy4HmDJlygFeVfdookeRXtJSD0//JDSSN7wL6xfvHr8x+jA4/5ehC27R4MyWM0f1OJjhGIOaAAARTUlEQVSY2RDgf4CvufsOS+nJFNs3vKfn2Ju9ncPdbwNuA6isrOzVcrRLuObmEumxRFuY1HDDktA4/u7rsGNjWJtjzIxQRTXvizDt5NDuMWp6Vk4xkkt6FEzMrJAQSP7b3X8fkzeb2Xh33xirsapj+npgcsruk2LaenZXWbWnPxXTJ3WSf2/nyLhk0ikqUJuJyF61tYRpRVoboa0ZmnfCxlfC3Ub1Sti5EZq2h7zl00J33CnzYNYFMO2kzJZdOtWT3lwG3A6scvefpGxaAFwCXB+fH0pJv8LM7iU0wG+PweBR4Adm1t4adibwLXffamY7zGweofrs08DP9nGOjNN0KiKESQtr3gyPbWtDQ3hjLdRXh66429buHgCYatgUGDcrBI5Dzwx3HsVD+r78csB6cmdyAnAxsMzMlsa0/0P4gP+tmV0GvAN8LG5bSOgWvJrQNfgzADFofA94Kea7rr0xHvgSu7sG/zE+2Ms5Mi6hKegl17iHaqj1i2H142EMR+PWjnmKysJo8cGjYOKxcMTHYPgUKCoNDeKFg2DsrFBlJf1ST3pzPQN09al5eif5HfhyF8e6A7ijk/RFwKxO0ms6O0c2SCSdAt2ZyEC0cxO88yy8+0YY7Ne0Heq3hDaN9uBRMhwO+3BYNnbEwTDyYBg+Ve0ZOUCjctIskdTcXNLPVK8K1U5NO8JU6Jv+Hhu7d6Y8dnScJn3QCBg0PDSETz8nVEtNnhOmSs/Lz9y1SMYomKRZ0jU3l2SJ1kaof3f3YkuNtaF7bVsTJFqh5g2oWhzW2khVMhxGTIPiMiiNz0VDoLwCpr4/VEdprIbsQcEkzTTORDKivgaW3x+qoqpXhilENi0jTCrRhUHlITCc/SOYVAklw8IUI6WjQbM4yAFSMEmzpGuiR+kFbc0hONSu6Vj91FIX7j7efCLcfVh+GMA3ZHSY5Xb45Ljo0sgQPIpKwySGefnhDkR30ZImCiZpltB0KtJdLQ2h62wyEWa23bg0NHbXrA5tGK31e+xgofpp0HCYPBdO+VYY0JdfmJHiS25TMEkzNcDLfql9J4y3aNwKrz8aBuzVrE5Z3pVwBzFsUqiKOujUsB74qPdBydDQjlFYquooyRoKJmmmrsHSqfp3YcUDsGFpGPn91lO7B+0VDwujuqd/KPaGKghBZMrxChbSbyiYpJlGwOeoloZwp7H1Lah9Gxq2hnEYzTtg52ZY93y46ygdA2VjYe4X4bBzQrvFyEM0DkP6PQWTNEtqBPzA19oEbzwaek7VrgnPrz4CiZbdefKLQs+o4jIoHRUmJTzyEzB2ZsaKLdKbFEzSTHcmA1QyCZteCdVUf70BdsTVEQpLw9xRR18MFSeG9cJHHBTaNURyiIJJmmlurn6uuQ7e/EsYBd64LXS/TbZC9atQvSLkmXAMnHczjD0izCWl37eIgkm6JTVosX9ItMELt8KrC+OI8JbwvH09tDWC5YVBfEVloattyTA472ehmmrCMQogIntQMEmzhKs3V9ZIJkJDeN3msMjS5pWhJ9WOjWGd8ObtMOHoMKCvoCS0cxx8Ohx+HkyaAwVFmb4CkX5DwSTNNM4kw5rrYNUCePE22Ph38MTubUVDoGw8DB0Ps84PExQeeqbuMkTSQMEkzcIIeH049anGbfD//SjMSbXuRWhtCMu4nvg1GDIuTC0yanoYHa7fjUivUDBJI3fX3Fzp4B4avhMtYU6quk2h+21LQ2zfaA7dc7e+GRrLt60FDMYfCbM/BrMvDFOiK3CI9BkFkzRKxgladWeyn1obQ4P363+CZb8LA/xaGsLkhS11+96/qAwqTgir9s34cAgmIpIRCiZplIjRJF8zYAQ7N0PVi2HtDE/CllfDsq71cX2N1IkLJx0XekkVDY5tG+OgcHCYWmTI2PC+uCyso9HeWF4yTHcfIllCwSSNkh6CSU5Uc7XUh8kKW+pCldTmFSFYNGyNgaIhTFzY1pSyk8HUE2Dq9DAqfPCIECgmVoZlXkWk31IwSaP2O5N+3TXYPazIt/XtOMdUTWjgbtoeHonmMMfU6r+ErrWpysbD4BgkSkfDlPfDkReGO428/LCeRumozFyXiPQqBZM0aovBpN+MgHcPExNuWgZL7gqN3NvXvzdIQAgIJcN2L9d68Kkw49w4sG8IDJ8Cwyb2bflFJGsomKRRclebSZYGk7otoQ3j9UehaVtYQ6N2Tdg2bAqMnw1Tj4fyaWEN8PKK0LW2ZKgWXBKRvVIwSaOE93EwcQ/rZNRtDm0YrfXhublud4+o9lX6Nq8IXWwh3E2UjoYxM+H9V4QpQiZWasS3iHSbgkkaJXurmqt5Z5hDqnpl6E7bWg81b4UpQjo0cHeivSfUQafAuCPC3ceU9+tOQ0TSSsEkjdJ6Z1K3JcwjtXkl/OV7sGM95BWGrrOFpWGBpcrLoHxqCBhFQ2K32tLQhbZoSOhCq6nQRaQPKJik0a5xJl3dmbiHLrMt9WFkd2sDvHIvVL0UelC1NYX0tiao37J7v1Hvg0sehqknahlXEclKCiZplIxLeu+6M3EP031ULYKVD8G7r4e1MVJZHkw8FoZP3T0gr6A49I4a9b4wKeH4oxVERCSrKZikUVsyCTjD696E5x+GFQ/AuhfCxinvh/d/KUx3Xjg4BIy8QpgyN6zMJyLSj/XbYGJmZwM3A/nAf7r79RkrTDIBKx9k1PI/8Vzx44x/cmtIH3EQfPhGmPWPoQeViMgA1S+DiZnlA7cAZwBVwEtmtsDdV/ZJAZLJMDp861vhsfIheOdvlBYP56/J6Uyp/Admf+AjoXFcRCQH9MtgAswBVrv7WwBmdi8wH0h/MHEP4zhq1+CblpNY8SC2YSn5rTt3ZanPK+OeEf+LH244miR5/PKQY5ldPi7tRRERyVb9NZhMBNalvK8C5vbGiZb95l854vWfAWDAm8lJvJicyzKfxpvJCaxjHIPKxzHYC/n4nGGMLivh+INH9kZRRESyVn8NJvvFzC4HLgeYMmVKt45RP/lkflvr1BRPoXD4BJKjZ1A2qIgrDx/LsEGFmFn2Tp8iItJH+mswWQ9MTnk/KaZ14O63AbcBVFZWendONO+kM5h30hnd2VVEJGf018ELLwGHmtk0MysCLgQWZLhMIiI5q1/embh7m5ldATxK6Bp8h7uvyHCxRERyVr8MJgDuvhBYmOlyiIhI/63mEhGRLKJgIiIiPaZgIiIiPaZgIiIiPaZgIiIiPWbu3RrL1++Y2RbgnW7uPgp4N43FybSBdD26luyka8leB3o9U9199L4y5Uww6QkzW+TulZkuR7oMpOvRtWQnXUv26q3rUTWXiIj0mIKJiIj0mILJ/rkt0wVIs4F0PbqW7KRryV69cj1qMxERkR7TnYmIiPRYTgUTM7vDzKrNbHlK2pFm9pyZLTOzh81saMq2b5nZajN7zczOSkk/O6atNrOrUtKviGluZqP6ybWsifmXmtmilPT7YtrSmGdpNlyLmY00syfNrM7Mfp6Sf7CZ/cHMXjWzFWZ2fcq2b5jZSjP7u5k9YWZTe/FaJsfyrYzl+GpMH2Fmj5nZG/G5PKabmf00/m7+bmbHpBzrkpj/DTO7JCX9qfh7bP/9jOkH1zLFzP5sZqvi8Spi+u1m9krMf7+ZDenja/mn+D5pZpV77POe/xkzKzGzF2OZV5jZtSn5TzOzJWa23MzuMrN+O5Fut7h7zjyADwDHAMtT0l4CTo6vPwt8L74+HHgFKAamAW8SprvPj68PAopinsPjPkcDFcAaYFS2X0vcts+yAv8BXJ0l11IKnAh8Afh5Sv7BwKnxdRHwNPCh+P5UYHB8/UXgvl68lvHAMfF1GfB6/Pn/GLgqpl8F/Ci+Pgf4I2FV6HnACzF9BPBWfC6Pr8vjtqeAyj74f0nLtaSU+Yz4ekjK72NoSp6ftB+3D69lBjB9z59pV/8z8dqGxDyFwAvxWvMIS4m/L267Drist39H2fTIqTsTd/8rsHWP5PcBf42vHwP+Mb6eD9zr7s3u/jawGpgTH6vd/S13bwHujXlx95fdfU3vXkWQpmvZJzMz4GPAb3pc6C4cyLW4e727PwM07XGMBnd/Mr5uAZYQVuDE3Z9094aY9fn29N7g7hvdfUl8vRNYBUwk/A7uitnuAj4SX88H7vbgeWC4mY0HzgIec/et7l5L+Bmc3Vvl7ky6rsXMDgcK3P2xeKy69t+Hu++AXX9ng4BeacTt6lrcfZW7v9bJLp3+z8Rrq4t5CuPDgZFAi7u/Hrel/v/lhJwKJl1YQQwGwD+xezngiYRvGu2qYlpX6dngQK8Fwj/Cn81ssZld3skxTwI2u/sbvVDevenqWvbJzIYD5wJPdLL5MsK3514Xq3KOJnx7HevuG+OmTcDY+Lq7f2e/ilVc/xo/iHtVD6/lfcA2M/u9mb1sZv9uZvkpx/5VPM5hwM968zri+SrYfS1d6fLnb2b5sdq3mhDwXyCMKC9IqSq7gAP4mx0IFExCFcqXzGwx4fa3JcPl6YnuXMuJ7n4M8CHgy2b2gT22f4JevCvZi279XmI99W+An7r7W3ts+xRQCfx7msvaWTmGAP8DfK3923c7D/UgPfkGfpG7H0EI9CcBF/fgWPuUhmspIJTzX4DjCFXEl6Yc4zPABMLdwsfTVvBO7O1a9pe7J9z9KMId7hwzmxV/DhcCN5rZi8BOIJGucvcHOR9M3P1Vdz/T3Y8lfAi9GTetp+M3i0kxrav0jOvGteDu7c/VwAOkVH/FD+aPAvf1fuk72su17MttwBvuflNqopl9EPg2cJ67N6e3tB2ZWSHhA+u/3f33MXlzrL4iPlfH9AP+O0v5ne0E7mE/qyy7I03XUgUsjVXDbcCDhDayXdw9Qagy7rWqoS6upSv7/D93923Ak8TqR3d/zt1Pcvc5hCra18khOR9M2nvCmFke8B3g/8ZNC4ALzazYzKYBhwIvEhqGDzWzaWZWRPg2sqDvS/5eB3otZlZqZmVxn1LgTGB5yiE/CLzq7lV9dQ3t9nIte9vn+8Aw4Gt7pB8N/JIQSKo72zddYpXT7cAqd/9JyqYFQHuPrEuAh1LSPx17Qs0DtscqpEeBM82sPPaWOhN41MwKLPYUjB+OH6bj7ywbr+UlQvtJ+2SBpwErY75DUs51HvBqH19LV7r6nxkdq1Exs0HAGe1lTvmbLQauZD/+ZgeU3mzdz7YH4RvuRqCV8G3pMuCrhG8QrwPXEwdyxvzfJnwjfo3YMyimnxPzvwl8OyX9n+Nx24ANwH9m87UQqhteiY8VqdcSt98JfCELfy9rCA32dTH/4YRvjk6oKlkaH5+L+R8HNqekL+jFazkxluPvKec7h9BA+wTwRizPiJjfgFvi72YZHXsUfZbQ8Lsa+ExMKwUWx+OvAG4m9szL8ms5Ix5nWfy7KiJ8mf1bTFsO/Dcpvbv66FrOj39DzfFv5NF9/M/MBl6Ox1lOSi9HQvXpqpj/a739f5NtD42AFxGRHsv5ai4REek5BRMREekxBRMREekxBRMREekxBRMREekxBRORDDKz6+KAyj3TTzGzRzJRJpHuyK0pkkWyjLtfnekyiKSDgolIHzGzfwU+BWwhTCK4GJgFPOLu95vZ2cBNQAPwTMYKKtINquYS6QNmdhxh3qkjCZNq7rkQUwnw/wizHR8LjOvrMor0hIKJSN84AXjI3Zs8TND48B7bDwPedvc3PExL8es+L6FIDyiYiIhIjymYiPSNvwHnxjXEhxBm+031KlBhZgfH95/o09KJ9JAa4EX6gLu/ZGYLCLPNbibMlLs9ZXtTXOnyD2bWQFjDviwjhRXpBs0aLNJHzGyIu9eZ2WDC4kmXe1yXXKS/052JSN+5zcwOB0qAuxRIZCDRnYmIiPSYGuBFRKTHFExERKTHFExERKTHFExERKTHFExERKTHFExERKTH/n9WPWWqQpS9RAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# reports[reports.gid.str[:2] == '20'].merge(s_pool, on=['sid','bet_amount']).groupby(['gid']).agg(\r\n",
    "#     {'rate_return':'mean','win':'max'}).rolling(window=10).mean().plot()\r\n",
    "# reports[reports.gid.str[:2] == '20'].merge(s_pool, on=['sid','bet_amount']).groupby(['gid']).agg(\r\n",
    "#     {'rate_return':'mean','win':'max'}).mean()\r\n",
    "reports[reports.gid.str[:2] != '11'].merge(s_pool, on=['sid','bet_amount']).groupby(['gid']).agg(\r\n",
    "    {'profit':'sum','bet_amount':'sum'}).cumsum().plot()\r\n",
    "\r\n",
    "# reports[reports.gid.str[:2] != '19'].merge(s_pool, on=['sid','bet_amount']).groupby(['gid']).agg(\r\n",
    "#     {'profit':'sum','bet_amount':'sum','sid':'count','win':'count'}).groupby('sid').sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0      20\n",
       "1      20\n",
       "2      20\n",
       "3      20\n",
       "4      20\n",
       "       ..\n",
       "166    21\n",
       "167    21\n",
       "168    21\n",
       "169    21\n",
       "170    21\n",
       "Name: gid, Length: 22059, dtype: object"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reports.gid.str[:2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/reshape/merge.py:643: UserWarning: merging between different levels can give an unintended result (1 levels on the left,2 on the right)\n",
      "  warnings.warn(msg, UserWarning)\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/pandas/core/generic.py:3889: PerformanceWarning: dropping on a non-lexsorted multi-index without a level parameter may impact performance.\n",
      "  obj = obj._drop_axis(labels, axis, level=level, errors=errors)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([0.34002124, 0.37745304, 0.40774897, 0.43003599, 0.4524072 ,\n",
       "       0.48857078, 0.51793247, 0.57246054, 0.62504295, 0.69226987,\n",
       "       0.81161748])"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reports.merge(s_pool, on=['sid','bet_amount']).head()\r\n",
    "s_pool\r\n",
    "reports.gid.nunique()\r\n",
    "ser, bins = pd.qcut(X_val.probmax, 10, retbins=True)\r\n",
    "pd.qcut(euro_data_feed['probmax'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.4892792010440203"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# report.rolling(window=10).sum().rate_return.plot() # .loc[:['win','rate_return']] # .plot()\r\n",
    "# report.rate_return.cumsum().plot()\r\n",
    "report.rolling(window=10).mean().rate_return.describe()\r\n",
    "X_val.groupby(pd.qcut(X_val.probmax,10, labels=False)).agg({'comp1':['count','mean']})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{(0, 0, 0, 0, 0, 0, 0, 0, 0),\n",
       " (0, 0, 0, 0, 0, 0, 0, 0, 1),\n",
       " (0, 0, 0, 0, 0, 0, 0, 0, 2),\n",
       " (0, 0, 0, 0, 0, 0, 0, 1, 1),\n",
       " (0, 0, 0, 0, 0, 0, 0, 1, 2),\n",
       " (0, 0, 0, 0, 0, 0, 0, 2, 2),\n",
       " (0, 0, 0, 0, 0, 0, 1, 1, 1),\n",
       " (0, 0, 0, 0, 0, 0, 1, 1, 2),\n",
       " (0, 0, 0, 0, 0, 0, 1, 2, 2),\n",
       " (0, 0, 0, 0, 0, 0, 2, 2, 2),\n",
       " (0, 0, 0, 0, 0, 1, 1, 1, 1),\n",
       " (0, 0, 0, 0, 0, 1, 1, 1, 2),\n",
       " (0, 0, 0, 0, 0, 1, 1, 2, 2),\n",
       " (0, 0, 0, 0, 0, 1, 2, 2, 2),\n",
       " (0, 0, 0, 0, 0, 2, 2, 2, 2),\n",
       " (0, 0, 0, 0, 1, 1, 1, 1, 1),\n",
       " (0, 0, 0, 0, 1, 1, 1, 1, 2),\n",
       " (0, 0, 0, 0, 1, 1, 1, 2, 2),\n",
       " (0, 0, 0, 0, 1, 1, 2, 2, 2),\n",
       " (0, 0, 0, 0, 1, 2, 2, 2, 2),\n",
       " (0, 0, 0, 0, 2, 2, 2, 2, 2),\n",
       " (0, 0, 0, 1, 1, 1, 1, 1, 1),\n",
       " (0, 0, 0, 1, 1, 1, 1, 1, 2),\n",
       " (0, 0, 0, 1, 1, 1, 1, 2, 2),\n",
       " (0, 0, 0, 1, 1, 1, 2, 2, 2),\n",
       " (0, 0, 0, 1, 1, 2, 2, 2, 2),\n",
       " (0, 0, 0, 1, 2, 2, 2, 2, 2),\n",
       " (0, 0, 0, 2, 2, 2, 2, 2, 2),\n",
       " (0, 0, 1, 1, 1, 1, 1, 1, 1),\n",
       " (0, 0, 1, 1, 1, 1, 1, 1, 2),\n",
       " (0, 0, 1, 1, 1, 1, 1, 2, 2),\n",
       " (0, 0, 1, 1, 1, 1, 2, 2, 2),\n",
       " (0, 0, 1, 1, 1, 2, 2, 2, 2),\n",
       " (0, 0, 1, 1, 2, 2, 2, 2, 2),\n",
       " (0, 0, 1, 2, 2, 2, 2, 2, 2),\n",
       " (0, 0, 2, 2, 2, 2, 2, 2, 2),\n",
       " (0, 1, 1, 1, 1, 1, 1, 1, 1),\n",
       " (0, 1, 1, 1, 1, 1, 1, 1, 2),\n",
       " (0, 1, 1, 1, 1, 1, 1, 2, 2),\n",
       " (0, 1, 1, 1, 1, 1, 2, 2, 2),\n",
       " (0, 1, 1, 1, 1, 2, 2, 2, 2),\n",
       " (0, 1, 1, 1, 2, 2, 2, 2, 2),\n",
       " (0, 1, 1, 2, 2, 2, 2, 2, 2),\n",
       " (0, 1, 2, 2, 2, 2, 2, 2, 2),\n",
       " (0, 2, 2, 2, 2, 2, 2, 2, 2),\n",
       " (1, 0, 0, 0, 0, 0, 0, 0, 0),\n",
       " (1, 1, 0, 0, 0, 0, 0, 0, 0),\n",
       " (1, 1, 1, 0, 0, 0, 0, 0, 0),\n",
       " (1, 1, 1, 1, 0, 0, 0, 0, 0),\n",
       " (1, 1, 1, 1, 1, 0, 0, 0, 0),\n",
       " (1, 1, 1, 1, 1, 1, 0, 0, 0),\n",
       " (1, 1, 1, 1, 1, 1, 1, 0, 0),\n",
       " (1, 1, 1, 1, 1, 1, 1, 1, 0),\n",
       " (1, 1, 1, 1, 1, 1, 1, 1, 1),\n",
       " (1, 1, 1, 1, 1, 1, 1, 1, 2),\n",
       " (1, 1, 1, 1, 1, 1, 1, 2, 2),\n",
       " (1, 1, 1, 1, 1, 1, 2, 2, 2),\n",
       " (1, 1, 1, 1, 1, 2, 2, 2, 2),\n",
       " (1, 1, 1, 1, 2, 2, 2, 2, 2),\n",
       " (1, 1, 1, 2, 2, 2, 2, 2, 2),\n",
       " (1, 1, 2, 2, 2, 2, 2, 2, 2),\n",
       " (1, 2, 2, 2, 2, 2, 2, 2, 2),\n",
       " (2, 0, 0, 0, 0, 0, 0, 0, 0),\n",
       " (2, 1, 0, 0, 0, 0, 0, 0, 0),\n",
       " (2, 1, 1, 0, 0, 0, 0, 0, 0),\n",
       " (2, 1, 1, 1, 0, 0, 0, 0, 0),\n",
       " (2, 1, 1, 1, 1, 0, 0, 0, 0),\n",
       " (2, 1, 1, 1, 1, 1, 0, 0, 0),\n",
       " (2, 1, 1, 1, 1, 1, 1, 0, 0),\n",
       " (2, 1, 1, 1, 1, 1, 1, 1, 0),\n",
       " (2, 1, 1, 1, 1, 1, 1, 1, 1),\n",
       " (2, 2, 0, 0, 0, 0, 0, 0, 0),\n",
       " (2, 2, 1, 0, 0, 0, 0, 0, 0),\n",
       " (2, 2, 1, 1, 0, 0, 0, 0, 0),\n",
       " (2, 2, 1, 1, 1, 0, 0, 0, 0),\n",
       " (2, 2, 1, 1, 1, 1, 0, 0, 0),\n",
       " (2, 2, 1, 1, 1, 1, 1, 0, 0),\n",
       " (2, 2, 1, 1, 1, 1, 1, 1, 0),\n",
       " (2, 2, 1, 1, 1, 1, 1, 1, 1),\n",
       " (2, 2, 2, 0, 0, 0, 0, 0, 0),\n",
       " (2, 2, 2, 1, 0, 0, 0, 0, 0),\n",
       " (2, 2, 2, 1, 1, 0, 0, 0, 0),\n",
       " (2, 2, 2, 1, 1, 1, 0, 0, 0),\n",
       " (2, 2, 2, 1, 1, 1, 1, 0, 0),\n",
       " (2, 2, 2, 1, 1, 1, 1, 1, 0),\n",
       " (2, 2, 2, 1, 1, 1, 1, 1, 1),\n",
       " (2, 2, 2, 2, 0, 0, 0, 0, 0),\n",
       " (2, 2, 2, 2, 1, 0, 0, 0, 0),\n",
       " (2, 2, 2, 2, 1, 1, 0, 0, 0),\n",
       " (2, 2, 2, 2, 1, 1, 1, 0, 0),\n",
       " (2, 2, 2, 2, 1, 1, 1, 1, 0),\n",
       " (2, 2, 2, 2, 1, 1, 1, 1, 1),\n",
       " (2, 2, 2, 2, 2, 0, 0, 0, 0),\n",
       " (2, 2, 2, 2, 2, 1, 0, 0, 0),\n",
       " (2, 2, 2, 2, 2, 1, 1, 0, 0),\n",
       " (2, 2, 2, 2, 2, 1, 1, 1, 0),\n",
       " (2, 2, 2, 2, 2, 1, 1, 1, 1),\n",
       " (2, 2, 2, 2, 2, 2, 0, 0, 0),\n",
       " (2, 2, 2, 2, 2, 2, 1, 0, 0),\n",
       " (2, 2, 2, 2, 2, 2, 1, 1, 0),\n",
       " (2, 2, 2, 2, 2, 2, 1, 1, 1),\n",
       " (2, 2, 2, 2, 2, 2, 2, 0, 0),\n",
       " (2, 2, 2, 2, 2, 2, 2, 1, 0),\n",
       " (2, 2, 2, 2, 2, 2, 2, 1, 1),\n",
       " (2, 2, 2, 2, 2, 2, 2, 2, 0),\n",
       " (2, 2, 2, 2, 2, 2, 2, 2, 1),\n",
       " (2, 2, 2, 2, 2, 2, 2, 2, 2)}"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from  itertools import product\r\n",
    "set(list(combinations_with_replacement([2,1,0], 9)) + list(combinations_with_replacement([0,1,2], 9)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.18780687397708673 0.426759410801964\n"
     ]
    }
   ],
   "source": [
    "# 参照组，仅使用赔率来预测\r\n",
    "X_val = euro_data.merge(zcsf_data,on=['match_time','home'],how='inner')\r\n",
    "X_val = X_val[X_val.result_type != -1]\r\n",
    "\r\n",
    "# zcsf_data.head()\r\n",
    "pred_val = X_val.loc[:,['odds_final_lose','odds_final_draw','odds_final_win']].values\r\n",
    "X_val['argmin'] = pred_val.argmin(axis=1)\r\n",
    "X_val['argmax'] = pred_val.argmax(axis=1)\r\n",
    "X_val['argmid'] = np.argsort(pred_val,1)[:,1]\r\n",
    "X_val['probmax'] = pred_val.max(axis=1)\r\n",
    "\r\n",
    "\r\n",
    "X_val['comp1'] = X_val['result_type'] == X_val['argmax']\r\n",
    "X_val['comp2'] = X_val['result_type'] != X_val['argmin']\r\n",
    "\r\n",
    "print(accuracy_score(pred_val.argmax(axis=1), X_val[target_col]), 1- accuracy_score(pred_val.argmin(1), X_val[target_col]))\r\n",
    "\r\n",
    "lottery_95 = lottery[lottery.first_price_9 < lottery.first_price_9.quantile(0.95)]\r\n",
    "\r\n",
    "best_s = []\r\n",
    "\r\n",
    "for s in list(combinations_with_replacement([0,1,2], 9)):\r\n",
    "    \r\n",
    "    report = pd.merge(X_val.groupby('gid',as_index=False).apply(eval,s=s), lottery_95, on='gid')\r\n",
    "    report['rate_return'] = report.apply(lambda x: x['win'] *x['first_price_9'] / x['bet_amount'] -1, axis=1)# rate of return\r\n",
    "    if report.rate_return.mean() > 0:\r\n",
    "        print(s, report.win.mean(), report.win.sum(), report.rate_return.mean(), report.bet_amount.max())\r\n",
    "        if report.win.mean() > 0.3:\r\n",
    "            best_s.append((s,report.win.mean()))\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>match_type</th>\n",
       "      <td>瑞典超</td>\n",
       "      <td>瑞典超</td>\n",
       "      <td>挪超</td>\n",
       "      <td>巴甲</td>\n",
       "      <td>亚冠杯</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>match_rounds</th>\n",
       "      <td>第9轮</td>\n",
       "      <td>第9轮</td>\n",
       "      <td>第11轮</td>\n",
       "      <td>第9轮</td>\n",
       "      <td>小组赛</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>match_time</th>\n",
       "      <td>2021-07-04 21:00:00</td>\n",
       "      <td>2021-07-04 21:00:00</td>\n",
       "      <td>2021-07-04 21:00:00</td>\n",
       "      <td>2021-07-04 22:00:00</td>\n",
       "      <td>2021-07-04 22:00:00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>home</th>\n",
       "      <td>瓦尔贝里</td>\n",
       "      <td>赫根</td>\n",
       "      <td>斯塔贝</td>\n",
       "      <td>沙佩科</td>\n",
       "      <td>淡宾尼</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>result</th>\n",
       "      <td>1:1</td>\n",
       "      <td>2:1</td>\n",
       "      <td>0:2</td>\n",
       "      <td>0:2</td>\n",
       "      <td>0:4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>visiting</th>\n",
       "      <td>卡尔马</td>\n",
       "      <td>索尔纳</td>\n",
       "      <td>桑德</td>\n",
       "      <td>巴伊亚</td>\n",
       "      <td>全北</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_init_win</th>\n",
       "      <td>2.86</td>\n",
       "      <td>2.39</td>\n",
       "      <td>1.96</td>\n",
       "      <td>3.16</td>\n",
       "      <td>49.56</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_init_draw</th>\n",
       "      <td>3.09</td>\n",
       "      <td>3.22</td>\n",
       "      <td>3.51</td>\n",
       "      <td>3.01</td>\n",
       "      <td>17.77</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_init_lose</th>\n",
       "      <td>2.43</td>\n",
       "      <td>2.81</td>\n",
       "      <td>3.5</td>\n",
       "      <td>2.29</td>\n",
       "      <td>1.01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_final_win</th>\n",
       "      <td>2.91</td>\n",
       "      <td>2.2</td>\n",
       "      <td>2.24</td>\n",
       "      <td>3.12</td>\n",
       "      <td>34.81</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_final_draw</th>\n",
       "      <td>3.07</td>\n",
       "      <td>3.24</td>\n",
       "      <td>3.39</td>\n",
       "      <td>3.17</td>\n",
       "      <td>17.59</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_final_lose</th>\n",
       "      <td>2.46</td>\n",
       "      <td>3.23</td>\n",
       "      <td>2.98</td>\n",
       "      <td>2.25</td>\n",
       "      <td>1.01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>result_type</th>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>result_pay</th>\n",
       "      <td>3.07</td>\n",
       "      <td>2.2</td>\n",
       "      <td>2.98</td>\n",
       "      <td>2.25</td>\n",
       "      <td>1.01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_final_sum</th>\n",
       "      <td>8.44</td>\n",
       "      <td>8.67</td>\n",
       "      <td>8.61</td>\n",
       "      <td>8.54</td>\n",
       "      <td>53.41</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>win_minus_lose_final</th>\n",
       "      <td>0.45</td>\n",
       "      <td>-1.03</td>\n",
       "      <td>-0.74</td>\n",
       "      <td>0.87</td>\n",
       "      <td>33.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_init_sum</th>\n",
       "      <td>8.38</td>\n",
       "      <td>8.42</td>\n",
       "      <td>8.97</td>\n",
       "      <td>8.46</td>\n",
       "      <td>68.34</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>win_minus_lose_init</th>\n",
       "      <td>0.43</td>\n",
       "      <td>-0.42</td>\n",
       "      <td>-1.54</td>\n",
       "      <td>0.87</td>\n",
       "      <td>48.55</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_diff_win</th>\n",
       "      <td>0.05</td>\n",
       "      <td>-0.19</td>\n",
       "      <td>0.28</td>\n",
       "      <td>-0.04</td>\n",
       "      <td>-14.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_diff_draw</th>\n",
       "      <td>-0.02</td>\n",
       "      <td>0.02</td>\n",
       "      <td>-0.12</td>\n",
       "      <td>0.16</td>\n",
       "      <td>-0.18</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_diff_lose</th>\n",
       "      <td>0.03</td>\n",
       "      <td>0.42</td>\n",
       "      <td>-0.52</td>\n",
       "      <td>-0.04</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>gid</th>\n",
       "      <td>21073</td>\n",
       "      <td>21073</td>\n",
       "      <td>21073</td>\n",
       "      <td>21073</td>\n",
       "      <td>21073</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>argmin</th>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>argmax</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>argmid</th>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>probmax</th>\n",
       "      <td>3.07</td>\n",
       "      <td>3.24</td>\n",
       "      <td>3.39</td>\n",
       "      <td>3.17</td>\n",
       "      <td>34.81</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>comp1</th>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>comp2</th>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                        0                    1  \\\n",
       "match_type                            瑞典超                  瑞典超   \n",
       "match_rounds                          第9轮                  第9轮   \n",
       "match_time            2021-07-04 21:00:00  2021-07-04 21:00:00   \n",
       "home                                 瓦尔贝里                   赫根   \n",
       "result                                1:1                  2:1   \n",
       "visiting                              卡尔马                  索尔纳   \n",
       "odds_init_win                        2.86                 2.39   \n",
       "odds_init_draw                       3.09                 3.22   \n",
       "odds_init_lose                       2.43                 2.81   \n",
       "odds_final_win                       2.91                  2.2   \n",
       "odds_final_draw                      3.07                 3.24   \n",
       "odds_final_lose                      2.46                 3.23   \n",
       "result_type                             1                    2   \n",
       "result_pay                           3.07                  2.2   \n",
       "odds_final_sum                       8.44                 8.67   \n",
       "win_minus_lose_final                 0.45                -1.03   \n",
       "odds_init_sum                        8.38                 8.42   \n",
       "win_minus_lose_init                  0.43                -0.42   \n",
       "odds_diff_win                        0.05                -0.19   \n",
       "odds_diff_draw                      -0.02                 0.02   \n",
       "odds_diff_lose                       0.03                 0.42   \n",
       "gid                                 21073                21073   \n",
       "argmin                                  0                    2   \n",
       "argmax                                  1                    1   \n",
       "argmid                                  2                    0   \n",
       "probmax                              3.07                 3.24   \n",
       "comp1                                True                False   \n",
       "comp2                                True                False   \n",
       "\n",
       "                                        2                    3  \\\n",
       "match_type                             挪超                   巴甲   \n",
       "match_rounds                         第11轮                  第9轮   \n",
       "match_time            2021-07-04 21:00:00  2021-07-04 22:00:00   \n",
       "home                                  斯塔贝                  沙佩科   \n",
       "result                                0:2                  0:2   \n",
       "visiting                               桑德                  巴伊亚   \n",
       "odds_init_win                        1.96                 3.16   \n",
       "odds_init_draw                       3.51                 3.01   \n",
       "odds_init_lose                        3.5                 2.29   \n",
       "odds_final_win                       2.24                 3.12   \n",
       "odds_final_draw                      3.39                 3.17   \n",
       "odds_final_lose                      2.98                 2.25   \n",
       "result_type                             0                    0   \n",
       "result_pay                           2.98                 2.25   \n",
       "odds_final_sum                       8.61                 8.54   \n",
       "win_minus_lose_final                -0.74                 0.87   \n",
       "odds_init_sum                        8.97                 8.46   \n",
       "win_minus_lose_init                 -1.54                 0.87   \n",
       "odds_diff_win                        0.28                -0.04   \n",
       "odds_diff_draw                      -0.12                 0.16   \n",
       "odds_diff_lose                      -0.52                -0.04   \n",
       "gid                                 21073                21073   \n",
       "argmin                                  2                    0   \n",
       "argmax                                  1                    1   \n",
       "argmid                                  0                    2   \n",
       "probmax                              3.39                 3.17   \n",
       "comp1                               False                False   \n",
       "comp2                                True                False   \n",
       "\n",
       "                                        4  \n",
       "match_type                            亚冠杯  \n",
       "match_rounds                          小组赛  \n",
       "match_time            2021-07-04 22:00:00  \n",
       "home                                  淡宾尼  \n",
       "result                                0:4  \n",
       "visiting                               全北  \n",
       "odds_init_win                       49.56  \n",
       "odds_init_draw                      17.77  \n",
       "odds_init_lose                       1.01  \n",
       "odds_final_win                      34.81  \n",
       "odds_final_draw                     17.59  \n",
       "odds_final_lose                      1.01  \n",
       "result_type                             0  \n",
       "result_pay                           1.01  \n",
       "odds_final_sum                      53.41  \n",
       "win_minus_lose_final                 33.8  \n",
       "odds_init_sum                       68.34  \n",
       "win_minus_lose_init                 48.55  \n",
       "odds_diff_win                      -14.75  \n",
       "odds_diff_draw                      -0.18  \n",
       "odds_diff_lose                          0  \n",
       "gid                                 21073  \n",
       "argmin                                  0  \n",
       "argmax                                  2  \n",
       "argmid                                  1  \n",
       "probmax                             34.81  \n",
       "comp1                               False  \n",
       "comp2                               False  "
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_val.head().T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'euro_data' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-1-b5cf05998213>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0mpred_s\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mX_future\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0meuro_data\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmerge\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfuture_data\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mon\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'match_time'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'home'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mhow\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'inner'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0;31m# zcsf_data.head()\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'euro_data' is not defined"
     ]
    }
   ],
   "source": [
    "pred_s = [ (0, 0, 0, 0, 2, 2, 2, 2, 2)]\r\n",
    "pred_s\r\n",
    "\r\n",
    "X_future = euro_data.merge(future_data,on=['match_time','home'],how='inner')\r\n",
    "\r\n",
    "# zcsf_data.head()\r\n",
    "pred_future = lgb_model.predict_proba(X_future.loc[:,feat_cols_euro], num_iteration=lgb_model.best_iteration_)\r\n",
    "X_future['argmin'] = pred_future.argmin(axis=1)\r\n",
    "X_future['argmax'] = pred_future.argmax(axis=1)\r\n",
    "X_future['argmid'] = np.argsort(pred_future,1)[:,1]\r\n",
    "X_future['probmax'] = pred_future.max(axis=1)\r\n",
    "\r\n",
    "\r\n",
    "def predict(x,s):\r\n",
    "\r\n",
    "    x_sort = x.sort_values('probmax',ascending=False).iloc[:14]\r\n",
    "    candidates = []\r\n",
    "\r\n",
    "    for idx,pos in enumerate(s):\r\n",
    "        if pos == 0:\r\n",
    "            candidates += list(zip(*x_sort.iloc[idx:idx+1,:].loc[:,['argmax']].T.values))\r\n",
    "        elif pos == 1:\r\n",
    "            candidates += list(zip(*x_sort.iloc[idx:idx+1,:].loc[:,['argmax','argmid']].T.values))\r\n",
    "        elif pos == 2:\r\n",
    "            candidates += list(zip(*x_sort.iloc[idx:idx+1,:].loc[:,['argmax','argmid','argmin']].T.values))\r\n",
    "    \r\n",
    "    money = len(list(product(*(candidates)))) * 2\r\n",
    "\r\n",
    "    print([(a,b,c,'%.2f'%d) for a, b, c,d in \\\r\n",
    "           zip(x_sort.home.iloc[:9].values, \r\n",
    "               s, candidates, \\\r\n",
    "               x_sort.probmax.iloc[:9].values)], money) # len(candidates) * 2)\r\n",
    "    print('\\n')\r\n",
    "\r\n",
    "for s in pred_s:\r\n",
    "    print(s)\r\n",
    "    X_future.groupby('gid',as_index=False).apply(predict,s=s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(0, 0, 0, 0, 0, 1, 2, 2, 2) 0.35 0.314 108\n",
      "(0, 0, 0, 0, 0, 2, 2, 2, 2) 0.4 0.317 162\n",
      "(0, 0, 0, 0, 1, 1, 2, 2, 2) 0.35 0.356 216\n",
      "(0, 0, 0, 0, 1, 2, 2, 2, 2) 0.4 0.37 324\n",
      "(0, 0, 0, 0, 2, 2, 2, 2, 2) 0.4 0.436 486\n",
      "(0, 0, 0, 1, 1, 1, 2, 2, 2) 0.4 0.395 432\n",
      "(0, 0, 0, 1, 1, 2, 2, 2, 2) 0.5 0.464 648\n",
      "(0, 0, 0, 1, 2, 2, 2, 2, 2) 0.5 0.518 972\n",
      "(0, 0, 1, 1, 1, 1, 2, 2, 2) 0.45 0.491 864\n",
      "(0, 0, 1, 1, 1, 2, 2, 2, 2) 0.55 0.531 1296\n"
     ]
    }
   ],
   "source": [
    "list(combinations_with_replacement([0,1,2], 9))\r\n",
    "# lottery.shape\r\n",
    "lottery[lottery.first_price_9 < lottery.first_price_9.quantile(0.95)]\r\n",
    "X_test_cp = X_test.copy()\r\n",
    "X_test_cp['gid'] = 'test'\r\n",
    "pred_test = lgb_model.predict_proba(X_test_cp.loc[:,feat_cols_euro], num_iteration=lgb_model.best_iteration_)\r\n",
    "X_test_cp['argmin'] = pred_test.argmin(axis=1)\r\n",
    "X_test_cp['argmax'] = pred_test.argmax(axis=1)\r\n",
    "X_test_cp['argmid'] = np.argsort(pred_test,1)[:,1]\r\n",
    "X_test_cp['probmax'] = pred_test.max(axis=1)\r\n",
    "\r\n",
    "\r\n",
    "X_test_cp['comp1'] = X_test_cp['result_type'] == X_test_cp['argmax']\r\n",
    "X_test_cp['comp2'] = X_test_cp['result_type'] != X_test_cp['argmin']\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "for (s, win_rate) in best_s:\r\n",
    "    sample = []\r\n",
    "    for i in range(1000):\r\n",
    "        sample.append(X_test_cp.sample(14,replace=False ).groupby('gid',as_index=False).apply(eval,s=s))\r\n",
    "    sample = pd.concat(sample, axis=0)\r\n",
    "    print(s, win_rate, sample.win.mean(), sample.bet_amount.max())\r\n",
    "# best_s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(0, 0, 0, 0, 0, 0, 0, 0, 0),\n",
       " (0, 0, 0, 0, 0, 0, 0, 0, 1),\n",
       " (0, 0, 0, 0, 0, 0, 0, 0, 2),\n",
       " (0, 0, 0, 0, 0, 0, 0, 1, 1),\n",
       " (0, 0, 0, 0, 0, 0, 0, 1, 2),\n",
       " (0, 0, 0, 0, 0, 0, 0, 2, 2),\n",
       " (0, 0, 0, 0, 0, 0, 1, 1, 1),\n",
       " (0, 0, 0, 0, 0, 0, 1, 1, 2),\n",
       " (0, 0, 0, 0, 0, 0, 1, 2, 2),\n",
       " (0, 0, 0, 0, 0, 0, 2, 2, 2),\n",
       " (0, 0, 0, 0, 0, 1, 1, 1, 1),\n",
       " (0, 0, 0, 0, 0, 1, 1, 1, 2),\n",
       " (0, 0, 0, 0, 0, 1, 1, 2, 2),\n",
       " (0, 0, 0, 0, 0, 1, 2, 2, 2),\n",
       " (0, 0, 0, 0, 0, 2, 2, 2, 2),\n",
       " (0, 0, 0, 0, 1, 1, 1, 1, 1),\n",
       " (0, 0, 0, 0, 1, 1, 1, 1, 2),\n",
       " (0, 0, 0, 0, 1, 1, 1, 2, 2),\n",
       " (0, 0, 0, 0, 1, 1, 2, 2, 2),\n",
       " (0, 0, 0, 0, 1, 2, 2, 2, 2),\n",
       " (0, 0, 0, 0, 2, 2, 2, 2, 2),\n",
       " (0, 0, 0, 1, 1, 1, 1, 1, 1),\n",
       " (0, 0, 0, 1, 1, 1, 1, 1, 2),\n",
       " (0, 0, 0, 1, 1, 1, 1, 2, 2),\n",
       " (0, 0, 0, 1, 1, 1, 2, 2, 2),\n",
       " (0, 0, 0, 1, 1, 2, 2, 2, 2),\n",
       " (0, 0, 0, 1, 2, 2, 2, 2, 2),\n",
       " (0, 0, 0, 2, 2, 2, 2, 2, 2),\n",
       " (0, 0, 1, 1, 1, 1, 1, 1, 1),\n",
       " (0, 0, 1, 1, 1, 1, 1, 1, 2),\n",
       " (0, 0, 1, 1, 1, 1, 1, 2, 2),\n",
       " (0, 0, 1, 1, 1, 1, 2, 2, 2),\n",
       " (0, 0, 1, 1, 1, 2, 2, 2, 2),\n",
       " (0, 0, 1, 1, 2, 2, 2, 2, 2),\n",
       " (0, 0, 1, 2, 2, 2, 2, 2, 2),\n",
       " (0, 0, 2, 2, 2, 2, 2, 2, 2),\n",
       " (0, 1, 1, 1, 1, 1, 1, 1, 1),\n",
       " (0, 1, 1, 1, 1, 1, 1, 1, 2),\n",
       " (0, 1, 1, 1, 1, 1, 1, 2, 2),\n",
       " (0, 1, 1, 1, 1, 1, 2, 2, 2),\n",
       " (0, 1, 1, 1, 1, 2, 2, 2, 2),\n",
       " (0, 1, 1, 1, 2, 2, 2, 2, 2),\n",
       " (0, 1, 1, 2, 2, 2, 2, 2, 2),\n",
       " (0, 1, 2, 2, 2, 2, 2, 2, 2),\n",
       " (0, 2, 2, 2, 2, 2, 2, 2, 2),\n",
       " (1, 1, 1, 1, 1, 1, 1, 1, 1),\n",
       " (1, 1, 1, 1, 1, 1, 1, 1, 2),\n",
       " (1, 1, 1, 1, 1, 1, 1, 2, 2),\n",
       " (1, 1, 1, 1, 1, 1, 2, 2, 2),\n",
       " (1, 1, 1, 1, 1, 2, 2, 2, 2),\n",
       " (1, 1, 1, 1, 2, 2, 2, 2, 2),\n",
       " (1, 1, 1, 2, 2, 2, 2, 2, 2),\n",
       " (1, 1, 2, 2, 2, 2, 2, 2, 2),\n",
       " (1, 2, 2, 2, 2, 2, 2, 2, 2),\n",
       " (2, 2, 2, 2, 2, 2, 2, 2, 2)]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from itertools import product,combinations_with_replacement\r\n",
    "list(product(['a','b','c'],['1','2'],['A','B']))\r\n",
    "a = ['a','b','c'],['1','2'],['A','B']\r\n",
    "a = list(zip(*X_val[X_val.gid == '21073'].loc[:,['argmax','argmid','argmin']].head(9).T.values))\r\n",
    "b = list(zip(*X_val[X_val.gid == '21073'].loc[:,['result_type']].head(9).T.values))\r\n",
    "\r\n",
    "# len(a)\r\n",
    "# list(product(*(list(range(3))*9)))\r\n",
    "# len(list(product(*[[0,1,2]]*9)))\r\n",
    "aa = list(combinations_with_replacement([0,1,2], 9))\r\n",
    "aa\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "19683\n",
      "1\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(len(list(product(*a))))\r\n",
    "print(len(list(product(*b))))\r\n",
    "c = list(product(*b))\r\n",
    "d = list(product(*a))\r\n",
    "[-1]*8  in d\r\n",
    "# list(product(*a))[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7f53c9cd4510>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from lightgbm import plot_importance\r\n",
    "%matplotlib inline\r\n",
    "import matplotlib.pyplot as plt \r\n",
    "plot_importance(lgb_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>max</th>\n",
       "      <th>comp</th>\n",
       "      <th>comp2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>(0.33, 0.46]</th>\n",
       "      <td>0.416099</td>\n",
       "      <td>0.404145</td>\n",
       "      <td>0.730570</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(0.46, 0.53]</th>\n",
       "      <td>0.495160</td>\n",
       "      <td>0.375000</td>\n",
       "      <td>0.703125</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(0.53, 0.62]</th>\n",
       "      <td>0.577375</td>\n",
       "      <td>0.466321</td>\n",
       "      <td>0.777202</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(0.62, 0.75]</th>\n",
       "      <td>0.683792</td>\n",
       "      <td>0.531250</td>\n",
       "      <td>0.807292</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>(0.75, 0.99]</th>\n",
       "      <td>0.858147</td>\n",
       "      <td>0.626943</td>\n",
       "      <td>0.797927</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   max      comp     comp2\n",
       "max                                       \n",
       "(0.33, 0.46]  0.416099  0.404145  0.730570\n",
       "(0.46, 0.53]  0.495160  0.375000  0.703125\n",
       "(0.53, 0.62]  0.577375  0.466321  0.777202\n",
       "(0.62, 0.75]  0.683792  0.531250  0.807292\n",
       "(0.75, 0.99]  0.858147  0.626943  0.797927"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "preds = np.zeros((X_test.shape[0],4))\r\n",
    "preds[:,:3] = lgb_model.predict_proba(X_test, num_iteration=lgb_model.best_iteration_)\r\n",
    "preds[:,3] = lgb_model.predict(X_test, num_iteration=lgb_model.best_iteration_)\r\n",
    "\r\n",
    "p = pd.DataFrame(preds)\r\n",
    "\r\n",
    "p['max'] = p.iloc[:,:3].max(axis=1)\r\n",
    "p['min'] = p.iloc[:,:3].min(axis=1)\r\n",
    "p['true'] = y_test.values\r\n",
    "p['comp'] = p.iloc[:,3] == p.loc[:,'true']\r\n",
    "p['argmin'] = preds[:,:3].argmin(axis=1)\r\n",
    "p['comp2'] = p['argmin'] != p.loc[:,'true']\r\n",
    "p.groupby(pd.qcut(p['max'],5,precision=0)).agg({'max':'mean','comp':'mean','comp2':'mean'})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7    31063\n",
       "8    27424\n",
       "6    19891\n",
       "9    10904\n",
       "5     8146\n",
       "4     2132\n",
       "3      397\n",
       "2       42\n",
       "1        1\n",
       "dtype: int64"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = [p.sample(14,replace=False).sort_values('min',ascending=True).head(9)['comp2'].sum() for i in range(100000)]\r\n",
    "pd.Series(a).value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>match_type</th>\n",
       "      <th>odds_final_win</th>\n",
       "      <th>odds_final_draw</th>\n",
       "      <th>odds_final_lose</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>result_type</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1022</td>\n",
       "      <td>3.423131</td>\n",
       "      <td>3.617329</td>\n",
       "      <td>2.893620</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>860</td>\n",
       "      <td>2.507221</td>\n",
       "      <td>3.525919</td>\n",
       "      <td>3.686686</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1326</td>\n",
       "      <td>2.113100</td>\n",
       "      <td>3.852783</td>\n",
       "      <td>4.844080</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             match_type  odds_final_win  odds_final_draw  odds_final_lose\n",
       "result_type                                                              \n",
       "0                  1022        3.423131         3.617329         2.893620\n",
       "1                   860        2.507221         3.525919         3.686686\n",
       "2                  1326        2.113100         3.852783         4.844080"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "euro_data.groupby('result_type').agg({'match_type':'count','odds_final_win':'mean','odds_final_draw':'mean','odds_final_lose':'mean'})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "84     1\n",
       "122    1\n",
       "221    2\n",
       "23     0\n",
       "30     1\n",
       "      ..\n",
       "63     1\n",
       "231    2\n",
       "146    1\n",
       "3      1\n",
       "51     2\n",
       "Name: result_type, Length: 963, dtype: int64"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['match_type', 'match_rounds', 'match_time', 'home', 'result',\n",
       "       'visiting', 'odds_init_win', 'odds_init_draw', 'odds_init_lose',\n",
       "       'odds_final_win', 'odds_final_draw', 'odds_final_lose', 'result_type',\n",
       "       'odds_final_sum', 'win_minus_lose_final', 'odds_init_sum',\n",
       "       'win_minus_lose_init', 'odds_diff_win', 'odds_diff_draw',\n",
       "       'odds_diff_lose', 'home_ysb', 'odds_ysb', 'away_ysb', 'home_hg',\n",
       "       'odds_hg', 'away_hg', 'home_bet365', 'odds_bet365', 'away_bet365'],\n",
       "      dtype='object')"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "asia_data.head()\r\n",
    "# euro_data.head()\r\n",
    "full_data = euro_data.merge(asia_data, on=['match_type','match_rounds','match_time','home','result','visiting','result_type'])\r\n",
    "full_data.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['odds_final_draw', 'odds_final_win', 'win_minus_lose_init', 'win_minus_lose_final', 'odds_hg', 'odds_final_sum', 'odds_diff_lose', 'odds_init_draw', 'away_hg', 'odds_ysb', 'odds_init_win', 'odds_final_lose', 'odds_diff_win', 'odds_init_lose', 'odds_bet365', 'odds_init_sum', 'odds_diff_draw', 'away_bet365', 'home_ysb', 'away_ysb', 'home_bet365', 'home_hg']\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/lightgbm/basic.py:1286: UserWarning: Overriding the parameters from Reference Dataset.\n",
      "  warnings.warn('Overriding the parameters from Reference Dataset.')\n",
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/lightgbm/basic.py:1098: UserWarning: categorical_column in param dict is overridden.\n",
      "  warnings.warn('{} in param dict is overridden.'.format(cat_alias))\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 58  43  38]\n",
      " [ 46  38  55]\n",
      " [ 47  60 108]]\n",
      "0.41379310344827586\n"
     ]
    }
   ],
   "source": [
    "\r\n",
    "import lightgbm as lgb\r\n",
    "import numpy as np\r\n",
    "# from pandas.tseries.offsets import MonthEnd, MonthBegin\r\n",
    "from sklearn.model_selection import train_test_split\r\n",
    "\r\n",
    "from sklearn.metrics import mean_squared_error, accuracy_score, confusion_matrix\r\n",
    "from sklearn.model_selection import KFold\r\n",
    "\r\n",
    "target_col = 'result_type'\r\n",
    "\r\n",
    "un_feat_cols = ['match_type', 'match_rounds', 'match_time', 'home', 'result',\r\n",
    "       'visiting', ]\r\n",
    "\r\n",
    "\r\n",
    "feat_cols = list(set(full_data.columns) - set(un_feat_cols) - set([target_col]))\r\n",
    "print(feat_cols)\r\n",
    "\r\n",
    "\r\n",
    "X_train, X_test, y_train, y_test = train_test_split(full_data.loc[:,feat_cols], full_data[target_col],test_size=.3,random_state =0)\r\n",
    "\r\n",
    "\r\n",
    "model = lgb.LGBMClassifier(random_state=1212)\r\n",
    "\r\n",
    "lgb_model = model.fit(X_train, y_train, \\\r\n",
    "                      eval_names=['train', 'valid'], \\\r\n",
    "                      eval_set=[(X_train, y_train), (X_test, y_test)],\\\r\n",
    "                      early_stopping_rounds=100,\\\r\n",
    "                    #   eval_metric='softmax',\r\n",
    "                      verbose=0)\r\n",
    "print(confusion_matrix(lgb_model.predict(X_test, num_iteration=lgb_model.best_iteration_), y_test) )\r\n",
    "print(accuracy_score(lgb_model.predict(X_test, num_iteration=lgb_model.best_iteration_), y_test) )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.axes._subplots.AxesSubplot at 0x7ff8e0d257d0>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAd4AAAEWCAYAAADIJfYaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzsnXd81EX6x98PPRCKFBEpQVQ6IdL1kAt6eIqCItgOD5CzYAP1AD1UBMuBgApiByVYABVOQM8OLKBSg6F5FEv4gVIEEyAUSXl+f8xs3CS7mwWSbLKZ9+u1r53vfKc83yHkyXxn5vOIquJwOBwOh6NoKBNuAxwOh8PhKE04x+twOBwORxHiHK/D4XA4HEWIc7wOh8PhcBQhzvE6HA6Hw1GEOMfrcDgcDkcR4hyvw+EoNojIKyLyaLjtcDgKE3HneB2Oko+IJAN1gUyf7Kaq+stptBkPvK2qDU7PupKJiCQAu1T1kXDb4ogs3IzX4YgceqlqtM/nlJ1uQSAi5cLZ/+kgImXDbYMjcnGO1+GIcESki4h8IyKpIrLezmS9924Rkf+JyGER+VFE7rD5VYBPgLNFJM1+zhaRBBF50qd+vIjs8rlOFpEHRWQDcEREytl680TkVxH5SUSGBrE1u31v2yIyUkT2ichuEblGRHqKyDYR+U1ERvnUHSMic0XkXfs860Skrc/9FiLiseOwWUR65+r3ZRH5WESOAP8A+gMj7bN/aMs9JCI/2Pa/E5E+Pm0MEpGvRGSSiKTYZ73C535NEZkhIr/Y+/N97l0lIknWtm9EJDbkf2BHicM5XocjghGR+sB/gSeBmsBwYJ6I1LFF9gFXAdWAW4DnRKSdqh4BrgB+OYUZ9E3AlUANIAv4EFgP1AcuBe4Tkb+G2NZZQCVbdzQwDbgZaA9cDDwqIuf4lL8aeN8+6yxgvoiUF5Hy1o7PgTOBe4F3RKSZT92/AU8BVYE3gXeACfbZe9kyP9h+qwNjgbdFpJ5PG52BrUBtYALwuoiIvfcWUBloZW14DkBELgDeAO4AagGvAgtFpGKIY+QoYTjH63BEDvPtjCnVZzZ1M/Cxqn6sqlmq+gWwFugJoKr/VdUf1LAU45guPk07nlfVnap6DOgI1FHVx1X1hKr+iHGeN4bYVjrwlKqmA3MwDm2Kqh5W1c3Ad0Bbn/KJqjrXln8W47S72E80MN7asRj4CPNHgpcFqvq1Hafj/oxR1fdV9Rdb5l1gO9DJp8gOVZ2mqpnATKAeUNc65yuAIaqaoqrpdrwBbgdeVdVVqpqpqjOB363NjgikxK7BOByOPFyjql/myosBrhORXj555YElAPZV6GNAU8wf4pWBjadpx85c/Z8tIqk+eWWB5SG2dcA6MYBj9nuvz/1jGIeap29VzbKvwc/23lPVLJ+yOzAzaX92+0VEBgAPAI1tVjTmjwEve3z6P2onu9GYGfhvqprip9kYYKCI3OuTV8HHbkeE4RyvwxHZ7ATeUtXbct+wrzLnAQMws710O1P2vhr1d+ThCMY5eznLTxnfejuBn1T1/FMx/hRo6E2ISBmgAeB9Rd5QRMr4ON9GwDafurmfN8e1iMRgZuuXAitUNVNEkvhjvIKxE6gpIjVUNdXPvadU9akQ2nFEAO5Vs8MR2bwN9BKRv4pIWRGpZDctNcDMqioCvwIZdvZ7mU/dvUAtEanuk5cE9LQbhc4C7sun/9XAYbvhKsra0FpEOhbYE+akvYhca3dU34d5ZbsSWAUcxWyWKm83mPXCvL4OxF6gic91FYwz/hXMxjSgdShGqepuzGa1l0TkDGtDN3t7GjBERDqLoYqIXCkiVUN8ZkcJwzlehyOCUdWdmA1HozAOYycwAiijqoeBocB7QApmc9FCn7pbgNnAj3bd+GzMBqH1QDJmPfjdfPrPxGzeigN+AvYD0zGbkwqDBcANmOf5O3CtXU89gXG0V1gbXgIG2GcMxOtAS++auap+BzwDrMA45TbA1ydh298xa9ZbMJva7gNQ1bXAbcAL1u7vgUEn0a6jhOEENBwOR0QgImOA81T15nDb4nAEw814HQ6Hw+EoQpzjdTgcDoejCHGvmh0Oh8PhKELcjNfhcDgcjiLEneN15KFGjRp63nnnhduMYsuRI0eoUqVKuM0otrjxyR83RsEpqeOTmJi4X1Xr5FfOOV5HHurWrcvatWvDbUaxxePxEB8fH24zii1ufPLHjVFwSur4iMiOUMq5V80Oh8PhcBQhzvE6HA6Hw1GEOMfrcDgcDkcR4hyvw+FwOBxFiHO8DofD4YhInnvuOVq1akXr1q256aabOH78jzDLQ4cOJTo6Ok+defPmISKFusHUOV6Hw+FwRBw///wzzz//PGvXrmXTpk1kZmYyZ44JRrV27VpSUvKGRj58+DBTpkyhc+fOhWqbc7wYcXURGe4nv7GIbCqotkXkcRH5i01fLCKbRSTJhkubaK8nnoyNDofD4fBPRkYGx44dIyMjg6NHj3L22WeTmZnJiBEjmDBhQp7yjz76KA8++CCVKlUqVLvcOd4iRFVH+1z2B8ap6tsAInI7UNOGUQsrx9IzafzQf8NtRrHln20yGOTGJyBufPLHjVFwTnd8ksdfSf369Rk+fDiNGjUiKiqKyy67jMsuu4wpU6bQu3dv6tWrl6POunXr2LlzJ1deeSUTJ/qd/xQYpcLxisgDwGB7OV1VJ4vIw8BATFzMnUCiLdseeMOW/dynjVbADEzw8DJAX1XdHqC/QG0nAB8BNYDrgb/a4ONVgWggUUTGqWrQGKciEge8AlQGfgAGq2qKiAwFhgAZwHeqeqOIVAGmYgJ2lwfGqOoCP23eDtwOULt2HUa3yQhmQqmmbpT5xeDwjxuf/HFjFJzTHR+Px8Phw4eZOXMmb7/9NtHR0YwZM4Z//etffPTRR0yePBmPx0NmZiYej4esrCweeOABHnroITweD6mpqSQmJpKWllaAT+WDqkb0B2gPbASqYJzbZp+8ykA1TODp4bb8BqCbTU8ENtn0VKC/TVcAovLpz1/bCUC/3Gl7nZbPc4zJZeOfbfpxYLJN/wJUtOka9vvfwM3ePGAbUCVYX02bNlVHYJYsWRJuE4o1bnzyx41RcApifN577z0dPHhw9vXMmTO1cePGWrduXY2JidGYmBgVET333HM1NTVVa9WqlZ1fsWJFrVevnq5Zs+ak+gTWagh+qTSs8XYFPlDVI6qaBvwHuNLmHVXVQ8BCABGpgXFYy2zdt3zaWQGMEpEHgRhVPRagv4v9tV1QiEh1a+NSmzUT6GbTG4B3RORmzKwX4DLgIRFJAjxAJaBRQdrkcDgcxY1GjRqxcuVKjh49iqqyaNEiHnjgAfbs2UNycjLJyclUrlyZ77//nurVq7N///7s/C5durBw4UI6dOhQKLaVBsdbIKjqLKA3cAz4WEQuCbNJ/rgSeBFoB6wRkXKAYF6Lx9lPI1X9X1itdDgcjkKmc+fO9OvXj3bt2tGmTRuysrK4/fbbw20WUDoc73LgGhGpbNc7+wD/tXlRIlIV6AWgqqlAqoh0tXX7exsRkSbAj6r6PLAAiA3Q3zJ/bRcUqnoQSBGRi23W34GlIlIGaKiqS4AHgeqYV+ufAfeKiNjnuKAg7XE4HI7iytixY9myZQubNm3irbfeomLFijnuB1rD9Xg8hTbbhVLgeFV1HWY9dTWwCrO5KhF4F1gPfAKs8alyC/CifTUrPvnXA5tsfmvgzSD9BWq7oBgITBSRDUAcZp23LPC2iGwEvgWet39IPIHZVLVBRDbba4fD4Sgytm7dSlxcXPanWrVqTJ48GYCpU6fSvHlzWrVqxciRIwHYs2cPUVFR2eWHDBkSTvMLnFKxq1lVnwWezZX3FPCUn7KJQFufrJE2fzwwPsT+ArU9yF/aXueVUMl5f4xPOgno4qdY19wZdi36jnxMdjgcjkKjWbNmJCUlAZCZmUn9+vXp06cPS5YsYcGCBaxfv56KFSuyb9++7Drnnntudp1II+JnvLkpCWIZftotpD3tDofDUbQsWrSIc889l5iYGF5++WUeeuih7FfAZ555ZpitKxpKxYy3MBCRWsCiXNlnAS/BqYtl2DPA1+XKLu+nXDlVLZSDgE5AIzhO/CA4bnzypzSNUfL4K3Ncz5kzh5tuugmAbdu2sXz5ch5++GEqVarEpEmT6NixIwA//fQTF1xwAdWqVePJJ5/k4osvztN2SSXiHG9RiWWo6gEgLlfbS4Cjto0ETkEsQ1WfEpFZwCxbbgFwnm0zHrNGmwI0B5qKyHygIeaY0BRVfU1ErgMuVNUHRGQYMExVm9gNYm+p6p/8jJsT0AgRJ34QHDc++VOaxsjj8WSn09PTmTdvHldddRUej4eDBw+yceNGxo8fz5YtW+jduzezZs2iYsWKzJo1i+rVq7N161b69u3LjBkzqFKlSvgepCAJ5bBvSfkQOWIZC4EBNn23tzwQDxwBzvEpW9N+RwGbgFqYmfcamz8Xs8GrPuYPhHH5jaMT0AiOEz8Ijhuf/CmtYzR//nzt0aNH9vVf//pXXbx4cfZ1kyZNdN++fXnG589//vNJi1mEA0qpgEakiGX8CZjtxy6A1ar6k8/1UBFZD6zEzHzPV9U9QLQ9ztQQM3vuZu1dXkA2OhwOx0kxe/bs7NfMANdccw1LliwBzGvnEydOULt2bVJTU8nMNCtxP/74I9u3b6dJkyZhsbkwiDTHWyBo8RDL0AD5R7wJ++r5L5jXym0xx4i8YTW+wRyN2opxthcDFwJfF5K9DofDEZAjR47wxRdfcO2112bnDR48mB9//JHWrVtz4403MnPmTESE9evXExsbS1xcHP369eOVV16hZs2aYbS+YIk0xxspYhlfAzfmtssP1YEUVT0qIs3JecRoOTDc2vgt0B34XY0Ah8PhcBQpVapU4cCBA1SvXj07r0KFCrz99tts2rSJdevWccklZo7z5z//mc2bN5OUlMS6devo1atAdYjCTkRtrlLVdXZT02qbNV1VE0XEK2ixj7xiGW+IiOKzuQqzGervIpIO7MEEGgjUX6C2T4dhwCz7qjtPJCEfPgWGiMj/MDPblT73lmNeMy9T1UwR2QlsKSD7HA6Hw3GKiFkPdjj+oFmzZrp169Zwm1Fs8Xg8xMfHh9uMYosbn/wJxxilpqZy6623smnTJkSEN954g8mTJ+P9v56amkqNGjVISkoiOTmZFi1a0KxZMwC6dOnCK6+8UmS2ltSfIRFJVNV8tSYjasZbEIjIGMwu4km58hsDH6lq64JoW0Qex8xGv7S6y68A6Zh12MeBnsDHqjriFPrpDbRUo7blcDgcDBs2jMsvv5y5c+dy4sQJjh49yrvv/nGa8Z///GeO18CRrBwVbpzjDQErlvExcI7VavZyqZrzvCeNqo4WkYdFZBLQALNpKgV4AHOe1q/ARohtL6SAwxE6HI6Sy8GDB1m2bBkJCQmAWVutUKFC9n1V5b333mPx4sVhsrB0Ueoc72kIbPwXuEJV43wENhbZqEB5BDZ8+gvUdgJGYOMFYAKQhTl33JkgAhsiUhZzXrgJZnPVAaC7qi4TkWXAPzDHkTqo6j22n0NAB8z53pGqOjfYGDnlquCUJtWhU8GNT/4U5Rglj7+Sn376iTp16nDLLbewfv162rdvz5QpU7IFKZYvX07dunU5//zzs+tFsnJUuClVjtc60lswzk2AVSKyHLODOA4zHuuwzhHjXO+xTs1XV3kIRiXqHRGpgIkMFKi/QG0DoKrT7c7qj7wOUUTSVDXOX5t2o9RWoCVwjm3zYhFZhQkLuF1EcitT1cOccW6OmQnncbxOuSp0SpPq0Kngxid/inKMPB4PW7duJTExkUGDBjFo0CCmTp3KnXfeyeDBZg7y3HPP0alTp2yVqRMnToRVOSotLS2H4lWkUaocLz4CGwAikkNgw+YFE9i4wqZXAA+LSAPgP4Fmu/gIbPi2XQAsxwhinAOMA24DlhJ4V/V8Vc0CvhORuv4KqOprwGtgNlfd2//qAjI18vB4PFxfAjd+FBVufPKnqMeoefPmjBs3jrvuuguAsmXLMn78eOLj48nIyOCGG24gMTGRBg0a5KkbHx/P7NmzqVu3bqHGqPWlpG6uCpVIO8dbJBQDgY1lGKfeCbP2XAMjJxlIlep3n7QEKONwOCKUs846i4YNG2bvYF60aBEtW7YE4Msvv6R58+Y5nO6vv/4a0cpR4aa0Od5IEdhYDVwEZKnqcSAJE3N3WdBaDoej1DJ16lT69+9PbGwsSUlJjBo1CsgZLcjLsmXLIlo5KtyUqlfNkSKwoaq/W0EMr2DGcuAmTMAGh8PhyENcXBxr167Nk+/d6exL37596du3bxFYVTpxAhqOPDgBjeBE+vrT6eLGJ38Keoz8iWN89tlnTJs2jTp16gDw73//m549e3LgwAH69evHmjVrGDRoEC+88EKB2VFQlNSfISeg4XA4HKUEf+IYn332Gffffz/Dhw/PUbZSpUo88cQTbNq0iU2bNoXJ4tJNRK/xisgYERnuJ7+xiJz0T5yIDBWR/4nIOyLSW0Qesvm1RCTJz6dWkLbSQujvYdvObyLyk00/fLJ2OxyOyMUrjvGPf/wDMOIYNWrUCFi+SpUqdO3alUqVKgUs4yhc3Iz35LgL+Iuq7rLXCwGsepXfc7eng6o+BTzlFdvILXwhImVPVd0qGE5AIzhOICI4bnzyp6DGKJg4BsALL7zAm2++SYcOHXjmmWc444wzTrtPx+lTotd4Q1WhstrIvipUn2NUqFr7qFBVwLwB8KtCJSKv2L622nZSyEcdSkSiMbuezwDKA4+o6gLbXpqqRgd4LgGmAj3sM5wA3rBtJgPv2nsTgKoY4YsKGEWrv2OODwVVt8r9jLkENNqPnjwtyMiXbupGwd5j4bai+OLGJ38Kaoza1DcCF3fddRdTp06lZcuWTJ06lSpVqnDNNddQvXr17DXfAwcO8OCDD2bX/fTTT9m6dSvDhg07fUMKmLS0NKKj/f56LNZ07949pDVeVLVEfoD2mF28VTASi5t98ioD1TDOZ7gtvwHoZtMTgU02PRXob9MVgKggfSYDtW16EPCCTScA72Mcd0vge5tfDqhm07WtPd4/dtKC9HMt8AVGEetsIBXo52PDSJ+ytXzSTwL32vSnQCvgKsxu6oeBisBP+Y1t06ZN1RGYJUuWhNuEYo0bn/wpyDHavXu3xsTEZF8vW7ZMe/bsmaPMTz/9pK1atcqRN2PGDL377rsLzI6CpKT+DAFrNQT/VZLXeLNVqFQ1DcihQqWqh7CvggOoUHlZAYyysW9jVPVU/w6dr6pZqvod4FWHEuDfIrIB+BKo73MvGN2A2aqaqaq/ALmVy331m1uLyHIR2Yg5a9zK5nvVrbph1K26Ah0puJjBDoejGBBIHGP37t3ZZT744ANatz7lwGqOAqbUr/Gq6iyrc3wlRoXqDlU9lRAd/tSh+gN1gPaqmm5fExfEjoYjPukE4BpVXS8igzAKVmDENO7EzJhHAyMIrm7lcDhKKF5xjBMnTtCkSRNmzJjB0KFDSUpKQkRo3Lgxr776anb5xo0bc+jQIU6cOMH8+fP5/PPPs5WsHIVPSXa8y4EEERmPcXR9MGu7M0RkHObZegGvqmqqiKSKSFdV/YoAKlQi0gijQlVQsbGqA/us0+0OxIRYbxlwh4jMBM4EugOzApStCuwWkfKY5/rZ5q/GzOx/VNXjNpzhHZhXzw6HI4LwJ47x1ltvBSgNycnJhWyRIxgl9lWzqq7DzPZWA6uwKlSY17DrgU/Iq0L1onVAvnrF1wObbH5r4M0CNPMdoIN9DTwA2BJivQ+A7cB31p4VQco+inn+r33bV9XfMRuzfNWtquLUrRyOiCA1NZV+/frRvHlzWrRowYoVf/yaeOaZZxAR9u/fD8A777xDbGwsbdq04aKLLmL9+vXhMttByZ7xoqrPAs/mynsKeMpP2USgrU/WSJs/HhgfYn+NfdIJGMePqg7KVS7afu8HLgzQVsAte3aR/p78bLDXLwMvByh7sU96FoFnzQ6Ho4ThTzQDYOfOnXz++ec0atQou+w555zD0qVLOeOMM/jkk0+4/fbbWbVqVbhML/WU2Bnv6VAIwhrfhFBmuoi0tOlRJ9m+X3sdDkfpJJhoxv3338+ECRMwpxINF110UfYZ3i5durBr1668jTqKjBI94y0kytrXzrm5VI1QRh5U9aL8GlXVW30uR2F2O7ch5w5rgN9VtXMohopIOVV1EccdjlJGINGML7/8kvr169O2bduAdV9//XWuuOKKgPcdhU9EOt5QhTVs2dzCGpmqGudHWKMmRojCX39pqhotIvHAGGA/Zr04EbhZVVVEPMBwoB8QZZ37ZlX1q3gVxF4PJgxgV2C2iGwDHrF2HsCcSd5r15UvBg5ae+5X1TdF5E3gLVX9ItD4OeWq4DhlpuC48cmf0xmj5PFXkpGRwbp165g6dSqdO3dm2LBhjBkzhmXLlvH5558HrLtkyRJef/11vvrqq1M13VEARJzjtY70FqAzZhPVKhFZDtyIkXUsB6zDOjKMc71HjarTRJ+mhgBTVPUdEamAEbMIhQswZ2l/wWx4+hOQ/VOuqg+JyD2BHK7PMwSyF6CCWnUUETkD6GKd+62Ytet/+vS9A/gR44TfxKw53+mnT1/lKka3cRPpQNSNMr84Hf5x45M/pzNGHo+H3377jdq1a3Ps2DE8Hg/nnnsuCQkJ/PTTTzRr1gwwwexbtWrFyy+/TM2aNfnhhx8YPXo048ePZ+PG4r3HMi0tDY/HE24zCo2Ic7z4CGsAiEgOYQ2bF0xYw/sOZgXwsIg0AP6jfmQkA7BarZazndU2xsfxhsjF/uz1wVdAowHwrojUw8x6f7L5XgGNHZjNV7eLSH0gxTs2vqjqa8BrYMIC3tv/6pM0ufTg8Xi4vgSGLCsq3PjkT0GM0XPPPUe9evVo1qwZHo+HSy+9lIkT/5g7NG7cmLVr11K7dm3+7//+j1tvvZX333+fiy7Kd2Us7JTUsIChUio3V4WC3QXcGziGEda4JMSqvkIamRTOHze+jnMqRrqyDeacrlegYxnGgV8MeIBfMa+5nYCGwxEBeEUzYmNjSUpKYtSowHs2H3/8cQ4cOMBdd91FXFwcHTrkLyfsKDwi0fEuB64RkcoiUgUjrPFfmxclIlUxwhqoaiqQKiJdbV2/whqYQAexBWhjuhW8CMQyf/YGoDp/iGYM9Gaq6k6MPvT5qvojZtY93LbtcDhKOF7RjA0bNjB//vw8kYeSk5OpXbs2ANOnTyclJYWkpCSSkpLyiG04ipaIc7wlRFjjNWCDiLwT5BkC2ZubMcD7IpKI2UTlyypgm00vx2hFu10VDofDEUZKdFhAR+HQrFkz9QquO/IS6etPp0skj0/jxo2pWrUqZcuWpVy5cjlmjs888wzDhw/n119/zZ5pejwe7rvvPtLT06lduzZLly7Nzo/UMSoISur4iEhIYQEjcXOVw+FwFBpLlizJdqxe/KlFpaamctddd/Hpp5/SqFEj9u3bV9SmOoopEfeqORino1glIrVEJCnXZ5eIbBORd0Skt4g8dJL2+LaZ6ZOudbLP5nA4woc/tahZs2Zx7bXXZjvjM888M1zmOYoZbsYbIla1KsfZWxHZAvzFe3wIG//3VNq0IhwBz/YWJU5AIzhOICI4kTg+yeOvBEBEuOyyyxAR7rjjDm6//XYWLFjgVy1q27ZtpKenEx8fz+HDhxk2bBgDBgwIh/mOYkZEOd7TVKzytpFbsaqvvzO8IvIK0AT4RETeAFKADqp6j4gkAIeADsBZwEhVnSsi0Zgd0mcA5YFHVHVBCM9VD7PZqhrm3+xOVV3uVcyyZfoBV6nqINv/MYyYx5l2TAZgxDNW5Q7qYOs7AY0QcQIRwYnE8fGKOUyYMIE6deqQkpLC8OHDOXbsGK+88goTJ07E4/Fw/Phxvv76a6pXr86OHTvYunUrzzzzDCdOnODuu+9GRGjYsGHEC0ScLpE+PhHjeItasUpVh4jI5UB3Vd1vg9D7Ug8j5tEcMxOeCxwH+qjqIRGpDawUkYWa/w63vwGfqepTIlIWqJzvgBjnfiHmLPJCjIrVrcAaEYlT1Rx61E5AI3ScQERwSsv4rF+/nkOHDnHgwAHuuccEE9u/fz/33nsvq1evpnPnzsTGxmbrIi9cuJBKlSoRHx9fYjcPFRWRPj6RtMabrVilqmlADsUqVT2EfRUcQLHKywpglIg8CMSo6rFTtGe+qmap6ndAXZsnmOAIG4AvMcd76gZqwIc1wC0iMgZoo6qHQ6jzoXXoG4G9qrpRVbOAzRg1LYfDcRIcOXKEw4cPZ6c///xzOnbsyL59+0hOTiY5OZkGDRqwbt06zjrrLK6++mq++uorMjIyOHr0KKtWraJFixZhfgpHcSBiZrwFharOEpFVGKf9sYjcoaqLT6EpXwUr746L/kAdoL2qpotIMn8oTQWzaZmIdLM2JYjIs6r6JuA7U87djrf/rFy2ZOH+3R2Ok2bv3r306dMHgIyMDP72t79x+eWXByzfokULLr/8cmJjYylTpgy33norrVu3LipzHcWYSPoFvBzjlMZjHF0fzNruDBEZh3nWXsCrqpoqIqki0lVVvyKAYpWINMIoVp2K4/VHdWCfdbrdgZhQKolIDLBLVaeJSEWgHUbQY6+ItAC22ucNZSbscDhOgSZNmrB+/fqgZZKTk3NcjxgxghEjRhSiVY6SSMS8ai4hilXvAB1syL4BwJYQ68UD60XkW+AGYIrNfwj4CPgG2F2AdjocEUnjxo1p06ZNDr3i3377jR49enD++efTo0cPUlJSANiyZQsXXnghFStWZNKkSeE02xFhOOUqRx6cclVwIn3jx+lSnMfHN2KPl5EjR1KzZk0eeughxo8fT0pKCk8//TT79u1jx44d2TrIw4fnkQA4ZYrzGBUHSur4hKpcFTEz3nASigBHEdiQFs7+HY6SyoIFCxg40MQXGThwIPPnzweM4EXHjh0pXz5YPBOH4+SJpDXeQsGqSC3yc+tSK4BRkH21IecOa4DfVbVzQfbjcJRW/Alg7N27l3r16gFw1llnsXfv3jBb6Yh0nOPNB3+KVQEoKyLYQwuKAAAgAElEQVTTgIswYfquBpoBr2DO3f4ADFbVFBHxAN9iYuVWwaz3/gtoA7yrqo8AiMjNwFC73rwKuEtVMwMZICJPAVdhxDOuVtW9InIuZm25Cka84z6v6EYgnHJVcCJRmakgKY7j41We+uqrr6hfvz779u2jR48eNG/ePEc5Eckh++hwFAbO8RYc5wM3qeptIvIe0BcYCdyrqktF5HHgMeA+W/6EqnYQkWEYh9ge+A34QUSewyhO3QD8ye6Cfgmz+zrQZq8qwEpVfVhEJgC3AU9iNmJNUdXZIjIkkPG+ylV16tThvcurnMZQRDZpaWkkuPEJSHEcH18VpO3bjRDdBRdcwOzZs6lWrRrz5s2jVq1aHDhwgKpVq+Yon5ycTFRUVIEqKUW6MtPpEunj4xxvwfGTjxpUInAuRqRjqc2bCbzvU96r67wR2KyquwFE5EegIUYQpD1GaQogCiN7GYgTmB3O3v572PSFwDU2PQvwuz0zt3JVSdzYUFSU1I0fRUVxHZ8jR46QlZVF1apVOXLkCKNGjWL06NFER0ezfft2+vbty/jx47nxxhtz2O/xeIiOji7QZyquY1RciPTxcY634PAVqcgEaoRYPpDAhQAzVfVfIfaf7iM9mYn7t3U4chBIAKNjx45cf/31vP7668TExPDee+8BsGfPHjp06MChQ4coU6YMkydP5rvvvqNatWrhfAxHBOB+ORceB4EUEblYVZcDfweW5lPHl0XAAhF5TlX3iUhNoKqq7jhJO1ZiXnu/i9GtdjhKJYEEMGrVqsWiRXn3T5511lns2rUrT77Dcbq440SFy0BgotVmjgMeD7Wi1Xh+BPjc1v8CE3jhZLkPeMC2cR7mDwKHw+FwhAnneAsAVU1W1dY+15NUdYyqJqlqF1WNVdVrVDXF3o9X1bU27VHVq3zq+t57V1XjbP32qroyiA3RPum5PqH/fga6qGosJjrT2gJ8dIej2JOZmckFF1zAVVeZ/2aLFy+mXbt2tG7dmoEDB5KRYUIYqipDhw7lvPPOIzY2lnXr1oXTbEcE4xxv5NMeSLIz3ruAf4bZHoejSJkyZUp2VKCsrCwGDhzInDlz2LRpEzExMcycOROATz75hO3bt7N9+3Zee+017rzzznCa7YhgSr3jFZExIpJHC+5U1ahE5JsQykwXkZY2Peok218lIkm5Pm0ClVfV5ara1s6au6nq9yfTn8NRktm1axf//e9/ufXWWwE4cOAAFSpUoGnTpgD06NGDefPmAUbBasCAAYgIXbp0ITU1ld27nQS6o+Bxm6sKGFW9KIQyt/pcjgL+fRLtF7qKlRPQCE5xFIgoThSH8fEKZtx3331MmDAhO45u7dq1ycjIYO3atXTo0IG5c+eyc+dOAH7++WcaNmyY3UaDBg34+eefs1WtHI6CIuIdr4g8AAy2l9NVdbKIPIzZ+LQP2Ik594qItAfesGU/92mjFTADqIB5S9BXVbcH6C9NVaNFJB4YA+zHRDlKBG5WVbXKVcOBfkCUVabarKr9/bRXBXgPaACUBZ5Q1XdtLN8OqrpfRDoAk1Q1XkTGAOcATYBGwP1AF+AKzHpvL1VN99NPtoBG7dp1GN0mI+CYlnbqRhnn4vBPcRgfj8fDihUrSE9P5/DhwyQlJXHgwAGWLl3KyJEjGTx4MOnp6XTo0IFjx47h8Xg4cOAA3377bfaab0pKComJiaSlFbwMeqQLRJwuET8+qhqxH8z65kaMqlM0sNknrzJQDfgeGG7LbwC62fREYJNNTwX623QFICpIn2n2Ox6zg7gBxlmvALraex6M08wuH6S9vsA0n+vq9jsZqG3THQCPTY8BvgLKA22Bo8AV9t4HwDX5jVvTpk3VEZglS5aE24RiTXEZn4ceekjr16+vMTExWrduXY2KitL+/fvnKPPZZ5/pddddp6qqt99+u86aNSv7XtOmTfWXX34pFNuKyxgVV0rq+ABrNQTfFOlrvF2BD1T1iKqmAf8BrrR5R1X1EFZBSkRqYJSmltm6vsEKVgCjRORBIEZVj4XY/2pV3aWqWUAS0PgUnmEj0ENEnrZngkM5DvSJmlntRsws+VOftk7FBoejxDFu3Dh27dpFcnIyc+bM4ZJLLuHtt99m3z4jAPf777/z9NNPM2SIUVLt3bs3b775JqrKypUrqV69unvN7CgUIt3xFgiqOgvojQk+8LGIXBJi1dxqVif9al9VtwHtME7zSREZbW9l8Me/XyV//VqH76to5VXFcjhKLRMnTqRFixbExsbSq1cvLrnE/Hfu2bMnTZo04bzzzuO2227jpZdeCrOljkgl0n8JLwcSRGQ8RoKxD2Ztd4aIjMM8fy/gVVVNFZFUEemqql9hAhIAICJNgB9V9XkRaQTEAosLyMZ0ESmvftZdbd9nA7+p6tsikgp4N2YlY16bf4J5He1wOAIQHx+frf07ceJEJk6cmKeMiPDiiy8WsWWO0khEz3hVdR2QAKzGhNWbrqqJGPnE9Rintcanyi3Ai3azk29ssOuBTTa/NYEjBJ0KrwEbROSdAPfbAKtt349hIg4BjAWmiMhazGza4XCQVzBj0aJFtGvXjri4OLp27cr335sTdcuWLaNdu3aUK1eOuXPnhtNkRylD/ngL6XAYmjVrplu3bg23GcWWSI+ccrqEe3yeffZZ1q5dy6FDh/joo49o2rQpCxYsoEWLFrz00kusXr2ahIQEkpOTOXToEJMmTaJ3797069evyGwM9xgVd0rq+IhIoqp2yK9cRM94HSAiHnvcyOGIeHILZoB5hXzo0CEADh48yNlnnw1A48aNiY2NpUwZ92vQUbRE+hpvoSAitTDRg3JzqaoeKC5tnipOQCM4xUEgojgTrvFJHn9lHsEMgOnTp9OzZ0+ioqKoVq0aK1cGlDx3OIoE53hPAesI40RkPiZofSVgCnCJiFyoqg+IyDBgmKo2sZuz3lLVP9ldyb0wge2/Ae7AiF28r6pxACJyPvCuqrbL3bfdUT1UVa+x1z0wGsz9gNcxZ3oVeENVn7PV/i4i0zH/3oNVdbWfdp2ARogUB4GI4ky4xmfcuHF5BDM8Hg+jR4/miSeeoGXLlsyZM4ebbrqJESNGZNfbs2cPmzdvpnbt2kVma8QLRJwmET8+oRz2dZ+A4hY17XcUsAmoD6yxeXMxG7fqY3ZSj/OtY9NvYZSkAJYAcTb9b+DeAH0KsAWoY69nYRx5e+ALn3I17LcHK8ABdMOKggT7OAGN4JTUw/1FRbjGx59gRs+ePbVJkybZZXbs2KEtWrTIUW/gwIH6/vvvF6mt7mcoOCV1fHACGkXCUBFZjwk239B+okWkqk3Pwji7izFHmwC620AHG4FLgFY2fzpwi4iUBW6wdfNg/3HfAm62oh8XYnZn/wg0EZGpInI5cMin2mxbdxlQzdZzOCIKf4IZCxYs4ODBg2zbtg2AL774IjtSkcMRLtyr5lPEajH/BbhQVY9a/eVKmNfHtwBbMc52MMY5/lNEKgEvYeQid1pdZa/4xTzMcaHFQKIGX9edAXwIHMe8os4AUkSkLfBXYAjmCJRXozr31nW3ld1RKihXrhzTpk2jb9++lClThjPOOIM33jBy7GvWrKFPnz6kpKTw4Ycf8thjj7F58+YwW+woDTjHe+pUB1Ks022OCUQAxtk+bj/fAt2BY6p60GemuV9EojHrsnMBVPW4iHwGvAz8I1jHqvqLiPwCPIJx/ohIbeCEqs4Tka3A2z5VbgCWiEhX4KCGJjvpcJRYfAUz+vTpQ58+ffKU6dixI7t27SpiyxyOU3C8InIG0FBVNxSCPSWJT4EhIvI/zOzWu1VyOeY18zJVzRSRnZg1WdSoY03DrAfvIad4B8A7GHWtz8mfdzDrvP+z1/Uxilze5YN/+ZQ9LiLfYgInDMbhcDgcYSMkx2tfo/a25ROBfSLytao+UIi2FWtU9XdMqD1/iE+5y3LVewQzU/VHV2CGqoaiRNUVmObT7nqMpnNuO+NDaMvhOG2OHz9Ot27dOHDgAJUqVaJfv36MHTuWxYsXM3z4cE6cOEH79u15/fXXKVeuHKrKsGHD+Pjjj6lcuTIJCQm0a5fnR9jhiDhC3VxVXU0kn2uBN9UEY/9L4ZlV+hCRD4ABmGNJ+ZVNxOhFv51fWYejqKhYsSKLFy/m9ddfJykpiU8//ZRvvvmGgQMHMmfOHDZt2kRMTAwzZ84E4JNPPmH79u1s376d1157jTvvvDPMT+BwFA2hOt5yIlIPs2Hno0K0p0QgIo1FZFNBtqmqfVQ1VlX3+/TzgYgk5fr8VVXbq2o3O+sOxd5kuwbscBQaIkJ0dDQA6enppKenU7ZsWSpUqEDTpk0B6NGjB/PmzQNgwYIFDBgwABGhS5cupKamsnv37rDZ73AUFaGu8T4OfAZ8raprrCDE9sIzywHGGYejX6dcFRynXJWX5PFXAiZAwa233sqePXu4++676dSpExkZGaxdu5YOHTowd+5cdu7cCcDPP/9Mw4YNs9to0KABP//8s4uB64h4QnK8qvo+8L7P9Y+4UHRl7Uapi4CfgauBZsArQGXgB4xKVIpdI/8Wc563CuaV8r8wkYfeteu+iMjNwFCgAiaa0l3+1ntFZDAQq6r32evbgJaYteP3gAZAWeAJVX3XVhspIldgYgr/TVW/z9WmU64KEadclRdflaHJkycD8Oijj9K8eXNGjhzJ4MGDSU9Pp0OHDhw7dgyPx8OBAwf49ttvycgwY5mSkkJiYiJpaWnheIQiJeKVmU6TiB+fUFQ2gKYYHeFN9joWeCSUupH4ARpjAtF7labeA24GNgB/tnmPA5P1D/Wop216GPALUA+oCOwCagEtMGdzy9tyLwEDAvQfjXHs3rLfYJx4X6xKlc2vbr+TgYdtegDwUbDnc8pVwSmpqjpFhXd8xo4dqxMnTsxx77PPPtPrrrtOVVVvv/12nTVrVva9pk2b6i+//FJkdoYT9zMUnJI6PhSwctU0zAwt3TrrDcCNIdaNVH5S1SSbTgTOxcg0LrV5MzGqVV4W2u+NwGZV3a1mjfZHzPGjSzGyj2ts7N1LMRrOeVDVNIzQxlX2DHF5Vd1o2+4hIk+LyMWa87zubJ/vC0/5qR2OAPz666+kpqYCcOzYMb744guaN2/Ovn37APj99995+umnGTJkCAC9e/fmzTffRFVZuXIl1atXd6+ZHaWCUNd4K6vqahHf2PCU9ndtvhubMoH8ZBi95bNy1c3C/DsIMFNV/5W7YgCmA6MwZ4RnAKjqNhFpB/QEnhSRRar6uC3vq1bllKscBc7u3bsZOHAghw4dIioqiuuvv56rrrqKESNG8NFHH5GVlcWdd97JJZdcAkDPnj35+OOPOe+886hcuTIzZswI8xM4HEVDqI53v4ici/2FLSL9ALf9MCcHMbKNF6vqcuDvwNJ86viyCFggIs+p6j4RqQlUVdUd/gqr6ioRaYg5uxsLICJnA7+p6tsikgrc6lPlBmC8/V5xsg/ncORHbGws3377bZ4g5hMnTmTixIl5yosIL774YhFa6HAUD0J91Xw38CrQXER+Bu7D6AE7cjIQmCgiG4A4zDpvSKjqd5jNUZ/b+l9g1oGD8R5mp3mKvW4DrLavqh8DnvQpe4Ztdxhwf6h2ORz5cfz4cTp16kTbtm1p1apV9sx10aJFtGvXjri4OLp27cr335v9fAkJCdSpU4e4uDji4uKYPn16OM13OIqcfGe8VoKwg6r+RUSqAGVU9XB+9SIZVU0GWvtcT/K53cVP+XiftAez2crfvXeBdwmdroA35i6q+hnm2Ffu/hvb5IMn0bbDERJe4Yzo6GjS09OJjY1l5cqV3HnnnSxYsIAWLVrw0ksv8eSTT5KQkADADTfcwAsvvBBewx2OMJHvjFdVs4CRNn2ktDvd4oCI1BCRbZjgC4tsnhPJcISF3MIZmZmZiAgiwqFDJjrlwYMHOfvss8NppsNRbAh1jfdLERmOmY0d8Waq6m+FYpUjGxFZhTl25MvfVbVpYfXpBDSC4wQ0/sBXOKN9+/Z8//339OrVi86dOzN9+nR69uxJVFQU1apVY+XKldn15s2bx7Jly2jatCnPPfdcDiENhyPSEXP0KJ9CIj/5yVZV9XvcpTQjIvMxx4MqYXSXUzAxex8QkWHAMFVtYtW/3lLVP4nIaKAXEIU5k3sH5ijR+6razrZ7PkZsw6+KvIgkY44w9cJEIbpOVbeISB1gFnA2ZlNVD6C9+khT2vq+AhrtR0+ehsM/daNg77FwW1E8aFO/eo7rtLQ0Ro0axf3338+MGTO48cYbadmyJXPmzGHnzp2MGDGCgwcPEhUVRYUKFVi4cCEej4dnn302TE8QHtLS0rLfEjjyUlLHp3v37omq2iHfgqEc9nWfkxLXqGm/ozDh/+oDa2zeXEwowPqYjVjjfOvY9FtAL5tewh8iHf8G7g3Sb7L3PnAXMN2mXwD+ZdOXY3am1w72DE5AIzgl9XB/UTFo0CCdMGGCNmnSJDtvx44d2qJFizxlMzIytFq1akVpXrHA/QwFp6SODwUpoCEiA/x9QqlbChkqIusx8Xkb2k+0iFS16VkYYY2LMbF7AbqLyCoR2QhcArSy+dOBW0SkLOYY0Kx8+v6P/U7EqGuB2YA1B0BVP8XMwB2OAiO3cEZiYiItWrTg4MGDbNu2DYAvvviCFi1aAOQIhLBw4cLsfIejtBDqGm9Hn3QljKrSOuDNAreoBCMi8ZhwiReq6lGr0VwJ8/r4FmArxtkOxqhH/VNEKmHkITuo6k4RGWPrAMzDHAtaDCSq6oF8TPAKc2QS+r+tw3FaeIUzMjMzycrKomPHjlx11VVMmzaNvn37UqZMGc444wzeeOMNAJ5//nkWLlxIuXLlqFmzZvZOZ4ejtBBqkIR7fa9FpAZ2FuXIQXUgxTrd5vxxtGg55kzv45hgCd0xO5IP2rEEI1ISDfTDvJJGVY+LyGfAy8A/TtGmrzHhHJ8WkcuAM06xHYfDL17hDC9ecfs+ffrQp0/eAFvjxo1j3LhxRWWew1HsCFVAIzdHgHMK0pAI4VNM7OL/YVSivNs4l2NeMy9TE21oJ/AVgKqmYrSwN2HO4K7J1eY7GFnJz0/RprHAZTZ+8HXAHsAdCXM4HI4wEdKMV0Q+5A993zKYEHTvB65ROlET9OCKALfFp9xlueo9glGt8kdXYIb6CQ+Yq43GPum1QLy9PAj8VVUzRORCoKO10+E4bY4fP063bt34/fffycjIoF+/fnTv3p1FixYxYsQIsrKyiI6OJiEhgfPOO49ly5Zx3333sWHDBubMmUO/fv3C/QgOR5ET6jqgrzJTBrBDVXcVgj0OH0TkA0zUo0tOo5lGwHtWgewEcFtB2OZwQF7Vqq5du1K3bl0mT57sV7WqUaNGJCQkMGnSpPwbdzgilFAdb09VzSE3KCJP584rqdgNTWmaU/oREWmMiV3b2k+1YO19o6oX5VNmOvCsqn4nIqNU9d+5y6hqH5/yaaoabZ1x7tf8D6qRi8yDqm4HLjgZ+x2OUMmtWpWenp6d70+1qnHjxgCUKXOqq1wOR8knVMfbg7w6v1f4yXMA+TldW8Y3ctAozDndUNrOu1ulgHHKVcFxylUGf6pVd999Ny1btgyqWuVwlHaCOl4RuRMjxtDERrbxUhWzW7ZEICIPYI7wgBGWmCwiD2NELPZhNjsl2rLtgTds2c992miFiXtbAbPO3dfOJv31552dxgNjgP2YoAqJwM2qqvao0XDMLuYoG1Fos6r2z+dZBJiA+cNHgSdV9V0RqYeR9KyG+Xe9U1WX253MYzGykz8At6hqmp92fZWrGN2mtIdbDkzdKON8Szve3csAkydPJi0tjUcffZRGjRrx7rvv8sQTT2SrVt10002MGDEiu/yePXvYvHkztWuXTnnxtLS0HOPnyEnEj08wdQ3M8ZjGwGwgxudTM1i94vQB2gMbgSpANLDZJ68yxlF9Dwy35TcA3Wx6IrDJpqcC/W26AhAVpM80+x2P2dzUAOOsVwBd7T0P5uxudvl8nsPbZl9MyMCyQF3g/zDhA/8JPGzLlMX8cVQbWAZUsfkPAqPz68spVwWnpKrqFAVjx47VO+64I1/VqoEDB+r7779f1OYVG9zPUHBK6vhQEMpVqnpQVZNV9SY1AdmPYWZZ0SLSKB+fXlzoCnygJrJSGkbd6Uqbd1RVDwELIft8cg1VXWbrvuXTzgpglIg8CMSoaqhqvatVdZeaKE9J/KEodTrPM1tVM1V1L7AUI3CyBqNyNQZooyaKVBfMDvSv7Yx6IOYPJ4ejQMitWvXFF18QExMTULXK4XCEfpyoF/AsRmh/H+aX9//4Q9ow4lHVWTZS0JXAxyJyh6ouDqGq79GdQlOUUtVlItLN2pcgIs9i5CG/UNWbCqNPhyO3atX111/PhRdeGFC1as2aNfTp04eUlBQ+/PBDHnvsMTZv3hzmp3A4ipZQncCTmNnTl6p6gYh0B24uPLMKlOUYRzQec5a2D2bmN0NExmHGoBfwqqqmikiqiHRV1a+A7PVWG03oR1V93s72YzFSjgVBuoiUV9X0EJ/nDhGZCdTE6D6PEJEYYJeqThORikA74CngRRE5T1W/F5EqQH1V3VZAdjtKOblVq8Cs/QZSrerYsSO7drmTiI7STah7+tPV6ASXEZEyqroEyD/0UTFAVdcBCcBqYBVmc1UiZiPSeuATcqpF3YJxVkn4iF5gZBc32fzWFKxO9WvABhF5J4SyH2DWoddjHP9IVd2DWU9eLyLfYgIqTFHVX4FBwGy7OW4F0LwA7XZEGMePH6dTp060bduWVq1a8dhjj+W4P3To0Bzh2nbs2MGll15KbGws8fHxzqk6HKEQykIw8CVmY9ILmI1WU4BvQqnrPiXv4zZXBaekbvwIhaysLD18+LCqqp44cUI7deqkK1asUFXVNWvW6M0336xVqlTJLt+vXz9NSEhQVdVFixbpzTffHNHjU1C4MQpOSR0fCjIsIHA1cBS4D6NH/APm9WyJRUTGiMhwP/mNra7xybY3VET+JyLviEhvEXnoNGzLc9znJOt/czr1HaUXf4IYIkJmZiYjRoxgwoQJOcp/9913XHKJEVbr3r07CxYsKHKbHY6SRqjRiY7YNcTzVXWmiFTGHFkptYhILWCRT1ZzzB8kQ9W8ll94Gm16z/V6uVTzDwmYjYYg4BEMJ6ARnEgV0AgkiNG5c2emTJlC7969qVevXo46bdu25T//+Q/Dhg3jgw8+4PDhwxw8eDAc5jscJQYxs+N8ConchhFXqKmq54rI+cArqnppYRt4qoQqmqGqk/yIZlyhqq1DFc0QkVdsX1ttOymYM7r3iEgCcAizJn4WZk12rg0BuAATpq888IiqLrDtpalqdO5+7L0Xgc9UdaGVj0xR1cEiMhg4V1UfDkXAw0+7vgIa7UdPnpb/IJdS6kbB3lAPk5Ug2tSvnuPaK4gxaNAgpk+fzuTJkylbtixXXHEFn3zyCQD79+/n+eefZ/fu3cTGxrJs2TKmTp3KWWedFY5HKDGkpaXlWCt35KSkjk/37t0TVTX//U+hvI/GnD+tAHzrk7cxlLrh+BAe0YxkoLZNDwJesOkETCQnb1Sn721+OaCaTde29nj/EAooqAHcCEy06dXASpuegYlClF2fIAIewT5ujTc4JXX96VQYO3asjhkzRuvWrasxMTEaExOjIqLnnntunrKHDx/W+vXrl6rxOVXcGAWnpI4PBbzG+7uqnvBeiEg5/ggTWBwJt2hGbuarapaqfodRmwKzY/rfdrfxl0B9n3vBWA5cLCItge+AvVYu8kLA39puQQt4OCIYf4IY7du3Z8+ePSQnJ5OcnEzlypX5/vvvATPjzcrKAkyA+8GDBwds2+FwGEJ1vEtFZBRm7bEHZgb3YeGZVTxQ1VlAb4xi18cicqrh+XxFNLxHlPoDdYD2qhoH7AUqhWDTz0AN4HKMHORyzFGnNDVqVcH6LjQBD0dksHv3brp3705sbCwdO3akR48eXHXVVQHLezwemjVrRtOmTdm7dy8PP/xwEVrrcJRMQv0l/BDwD8yr2juAj4HphWVUAVASRDOqA/tUNd0KkpyMlONKzA7zS4BawFz7cThOC3+CGLlJS/tj032/fv1cMHuH4yTJLzpRI1X9P/uacpr9FHtUdZ3d1LTaZk1X1UQR8Ypm7COvaMYbIqL4RCTCzCT/LiLpwB5CDN0XIu8AH4rIRmAtsOUk6i4HLlOjRrUDo2C1vABtczgcDkchkd+Mdz5GehARmaeqfQvfpIJBVZ/F6Ev75j2FkVHMXTYRaOuTNdLmjwfGh9hfY590AmZTFao6KFe5aPu9H7Mu66+toNv5VPV14HWbTsdsIvPXhwcTBcmbf08Ij+KIYI4fP063bt34/fffycjIoF+/fowdO5b+/fuzdu1aypcvT6dOnXj11VcpX748YF4n33fffaSnp1O7dm2WLl0a5qdwOEo2+a3x+komNilMQ4qKkiqccar2ORy+VKxYkcWLF7N+/XqSkpL49NNPWblyJf3792fLli1s3LiRY8eOMX26WUlKTU3lrrvuYuHChWzevJn3338/zE/gcJR88pvxaoB0qcSPaAYY4YwOqup1iictnBGgrzbk3GFdAbcj2XGaBFKm6tmzZ3aZTp06ZWsuz5o1i2uvvZZGjUwU0DPPPLPojXY4Ioz8HG9bETmEmflG2TT2WlW1WqFadwqEKpxhy+YWzvC24Vc4Q416VJxPuVcwZ3Nni8hpC2f4oqobc/XVGPjIpisBL9u2M4AHVHVJILtF5GZgqM1fBdylqpmBxtApVwWnpCpXBVOm8pKens5bb73FlClTANi2bRvp6enEx8dz+PBhhg0bxoABA8Jiv8MRKQR1vKpaomQhrSO9BeiM+eNglYgsx4hOxGGedx3W8WKc1D1qYtlO9GlqCCa6zzsiUoEA8piqOkRELge6q+p+EQK0lOYAACAASURBVBmUq0g9zJni5piZ8FzgONBHVQ+JSG1gpYgstIevQ+Vu0722EZHmwOci0tSf3SLSAhOt6E92B/VLmJ3bOaIr5VKuYnSbjJMwp3RRN8o435KGx+PJTk+ePDlbmap58+acc845AEyaNIkmTZqQmZmJx+Nhx44dbN26lWeeeYYTJ05w9913IyI0bNgwYD9paWk5+nLkxY1RcCJ9fCLtTGe2cAaAiOQQzrB5wYQzrrDpFcDDItIA+I/6kYkMkfl2R/h3IpJbOKMbkMUfwhl7TvI5pwKo6ha7s7mpP7tF5FKMatcaEQGIwsz8c6Cqr2HCE9KsWTO9t//VJ/2wpQWPx8P18fHhNqNAWLduHQcOHOCWW25h7NixlCtXjvfee48yZcz2j5UrVxIbG8sVV5j/GgsXLqRSpUrEB3l+j8cT9L7DjVF+RPr4hCqgUaoojsIZoRDAbgFmqmqc/TRT1TEF0Z+j5OFPmap58+ZMnz6dzz77jNmzZ2c7XYCrr76ar776ioyMDI4ePcqqVato0aJFuMx3OCKCSHO8y4FrRKSyiFTBCGf81+ZFiUhVbDhDVU0FUkWkq63rVzgDsx4bW4A2no5whpflWHvtK+ZGwNYAdi8C+onImbZ8TRtpylEKCaRMNWTIEPbu3cuFF15IXFwcjz/+OPD/7Z15mJTVlYffH4srAqKYh4ixI0H2pmXVgAoacMGoDEZNRNSBqDMmkKDImLigEx0SJIKKwSWAGldUNJM47rQgUUT2LagRDBJFXJDFRho488e91V00XdXd0F291Hmfp56636373Xu/Q9Gn7vY70K5dO04//XRyc3Pp0aMHw4YNo2PHjtX8FI5Tu6lTU81ZIJyR4B7gD7GOHcClZvaNpD36bWZfSLqesA5cDygkrBF/WBkP49QuUilT7diRes161KhRjBo1qiq75TjZRXkiKfgru14enSg9tSlySkFBgXXv3t1yc3Otffv2duONN5qZ2V133WWtWrUywDZs2LDHfW+//bbVr1/fpk+fXuE2a5N9qgu3UXpqq30oZ3SiOjXidRxndxKCGY0aNaKwsJDevXtzxhln0KtXL84666xSN7Ds3LmT0aNH079//8x32HGyAHe85SCFcAbAqRbO9pa3njWEc76fpSmTLJzRiLDz+Usz6ynpSsI08U5gC3C5hVCDSMoF7iXEGt4FdDezbZLyCceaEiEN+5vZHruanbpJKsGM4447LuU9d911F4MGDWLevHkpyziOs/e44y0HVkI4o4rbKhLOkDSGEO7v9vjxo2Y2OX52NkGL+vQYH/lPwMVmtjj+UChMqvYiM3unvH1wAY301AYBjYRYBqQXzCjJunXrmDFjBjNnznTH6zhVRFY6XknPAkcRjvFMJChOnWBmIyWNAEaY2TFxl/DDZtZL0o2EHdEHEgLOX0HQr55uZolAEq2BJxLXKbhW0hmEEehPLEQYag5MJuxOhhDybx1BEGNnVJ76uZklRyA6mGIZz/7AEjNbDEU/FCpqExfQKCe1QUCjpPhAKsGMbdu2MWfOHJo0aQLAmDFjuOCCC5g1axaffPIJy5cv5/DDD69Q23Vd/KAycBulp87bpzwLwXXtBTSL7wcCywgiFvNi3lOEnc9HEmQm/yf5nph+GPhhTM8E8mL6NoKDTNXuGuDXMT0E+EtMPwr0junvACtjegxwTYk6rgL+QZC+bB3zfhH79CJBmevapPL5hDjKi4AbAJVlH99clZ7auvHDzOzmm2+2cePGFV0fffTRu22uysnJsaOPPtqOPvpoO/jgg6158+Y2Y8aMCrVRm+2TKdxG6amt9qGcm6vq2jne8jJc0mJCQPmj4qtRPOd7FMERngScSHGc276S5sYjPKcAHWL+A8BlkuoTpBkfLaPtx5LeE2EBfwDcLWkRQVqycdR03gMzm2RmrYDRwPUxuwFBzeqi+D4wKlZBmGbuFJ/lRODiMvrn1CFSCWakYvXq1axZs4Y1a9Zw3nnncc8993DuuedmqruOkxVkneOV1Ifg6E4ws87AQsKU898I53pXEZztiQTHOCcGJbgHOC86sfspVpt6miA1eRYw38qe5i0t4lM94HgrVpc60sxShgiMPA4k/iJ+BMwys88sSGM+T4yjbGbr4vtmwo+CHmXU69QhUglm3HnnnbRs2ZKPPvqI3Nxchg0bVt1ddZysIRvXeJsQdgl/HQMMHB/zZwO3xNdCoC9QYGZfRV1ngM/iSPQ8wpQ0FnYOv0iIFjS0HO1fAIyN72/GvJeAnwPjACTlmdkiYDNhlzIxv7UV60YPABLpFwlrxwcB24GTgTvipqumFgI4NCT8OHilPEZy6gapBDOGDx/O8OHD0947bdq0KuqV42Q3WTfiBV4AGkhaSXCAb8X82YRp5lkWQuatBd6AInnJ+wnrwS+yu/oVBDWqXeyufpWKQyUtAUYAv4x5w4FukpZIWkHYVAXwv4Rp40WSTgR+Jml5nJIeSViDxsy+JOxwnkdYy11gZn8F9gdejO0tImzYur8cfXTqANu2baNHjx507tyZDh06cNNNNwFw9913873vfQ9JfPZZ8cm25557jtzcXPLy8ujWrRtvvPFGdXXdceo0WTfiNbNvKI5CVBIlldtNPcDMrqd4TbUkvYGplibGbawjJyZHl8j/jDACLln+XXbXiZ5dskxS2T8RjhQl520lRCZyspCKimeceuqpnH322UhiyZIlnH/++fz973ujaOo4TjqyccSbFkljJF1TSn6OpGWl5M8g7FCemKK+v5WjzQcktY/pX1W813vU93zS9LiTpaQTz8jJydmjfKNGjYihI9m6dWtR2nGcysUd7z5iZgPNLNeS1KgkzYjTw4uAg2L6tDR1DLOoQAXss+M1szPj9LiT5ezcuZO8vDyOOOII+vXrl1Y8A2DGjBm0bduWAQMGMGXKlAz10nGyi6ybapY0Evj3ePmAmU2Q9GvCeumnhLXd+bFsVyDx1+elpDo6AFOB/Qg/XgYlbXrCzAYmld1iZo0k9YnyjZ8BHWMbg83MYv41hE1bB0aHvdzMikIVJtU3CvjGzO6UdAfQ2cxOibF3h5rZRQlpSoLk5P8R1qq/T1jjPcfMCkrWm4wrV6WnNilX1a9fn0WLFrFx40YGDhzIsmXL0ob1GzhwIAMHDmTWrFnccMMNvPKK78VznMomqxxvdKSXAT0J67lzJc0GLiTINDYgCFDMj7dMBX5mZrMkjUuq6kpgopk9Imk/oH45u3Ac4fzvv4A5QC/iBi4AM/svST8zs3TylLOBq4E7Cc51/7hj+URgVinlWwM/NrOfSnoSGESJtWBw5aqKUBuVqwBycnKYNGkSF1wQthOUVK0qyYoVK3juuedSfp6KOq86VAm4jdJT1+2TVY6XsAlqRtx0hKRnCMdyZsTzr0j6c3xvSjiKk3BmD1O8KetN4NeSWgLPJI92y+BtM/so1r8IyCHJ8ZaT+UBXSY2Bbwg/FLoRHG9p50NWx6NJiXtzSqvUzO4D7gNo06aN/fyicyrYrewhPz+f80uJ6lPT2LBhAw0bNqRp06YUFBRwww03MHr06KJNVQcccAC9evUqkoR8//33adWqFZJYsGABkoo2W1WE/Pz8UqMeOcW4jdJT1+3ja7x7gZk9CpxN0Ft+Pk7zlodvktI72YsfPmZWCKwGLiWIfswmnDn+HrCyKtp0aicVFc94+umn6dixI3l5eVx11VU88cQTvsHKcaqAbPsjPBuYJmksYap5IGFtd6qk/yHY44fAvWa2UdJGSb3N7A2CHCMAMXjCB3Gd9TuEIz+vVVIfCyU1jA423XNcQ1irXko4wzs/aoU6DlBx8YzRo0czevToPfIdx6lcsmrEa2YLgGnA28Bcwuaq+cATwGLCRqRkcYzLgElxWjj5p//5wLKY3xF4qBK7eR+wRNIjacrMJsTYfdPM1gPbSHPG13Ecx6k5ZNuIFzP7PWGEmJx3K3BrKWXnA52Tsq6N+WMJqlflaa9RfM8nRApK5P8sKd0nKT2aEgIbpdT5KtAw6frYEp/nxGRiB3Ui/3acOsfatWsZMmQI69evRxKXX345I0aMYPHixVx55ZVs2bKFnJwcHnnkERo3DgqkS5Ys4YorrmDTpk3Uq1ePefPmccABB5TRkuM4lUFWjXgdpy7SoEEDxo8fz4oVK3jrrbeYNGkSK1asYNiwYYwdO5alS5cycOBAxo0LG/N37NjB4MGDmTx5MsuXLyc/P5+GDRuW0YrjOJVFVjneVOpTlVDvYQnBjBKvw0opW1bUoZJ1rpa0MqnO26Om8yJJL0n6dtI9fWL+ckmvJ+WvkbQ0fvZO5Ty1U1No0aIFXbp0AeCQQw6hXbt2rFu3jnfffZeTTjoJgH79+vH0008D8NJLL5Gbm0vnzmEy57DDDqN+/fKeiHMcZ1/JuqnmqiCGAkx39nav65Q0DfiLmT0FIKmxmV0T08OBG4Er4/Gne4DTzeyfko4oUWXfZHWtdLiARnpqkoBGQiij6HrNGhYuXEjPnj3p0KEDzz33HOeeey7Tp09n7dq1ALz77rtI4rTTTmPDhg1ceOGFXHvttdXRfcfJSrLR8daXdD9JSk5AG2AycBDwD+DfzezLqCi1kHBG9mCCJvN1QCfgiRg4AUmDCWdo9yNs2vrPdAETouJUf+AT4EIz2yCpFTAJaA58DfwUaEY4tnSypOsJCln/SKrqYIpj+v6EcKb4nwBm9mlFjOICGuWnJgloJIsMFBQUMGLECIYNG8aCBQu48sorufXWW7n22mvp1asX9erVIz8/n1WrVvHKK68wefJk9t9/f66++mrq169P166VE0+jrosfVAZuo/TUefuYWda8COIRO4C8eP0kMBhYApwc824BJsR0PvDbmB5BUJxqQQi39xFwGNCOEL6vYSx3DzAkTR8MuCimbwTujulXgdYx3RN4LaanAeeVqONWgrTlMqB5zJtAcNz5BKGMIUnlV1OsyHV5WXY69thjzUnNzJkzq7sLe7B9+3br37+/jR8/vtTPV61aZd27dzczs8cee8yGDBlS9Nktt9xiv/vd7yqtLzXRPjUNt1F6aqt9gHesHL4oq9Z4I6ttdyWnVgSFqsSa6IPASUnl/xzflxL0kz+2EFrwA0L83lMJoffmxeNFpwLHpGl/F+H4EgTpxt6SGhFG4NNjHfcSHHypmNmvzewoQhzgxO7oBrEfA4DTgBskJXY79zazLgTlrasknVSyTqf2YmYMHTqUdu3aMXLkyKL8Tz8Nkx67du3iN7/5DVdeGcI8n3baaSxdupSvv/6aHTt28Prrr9O+fftq6bvjZCPZONVcUsmprPB5ifK7Sty7i2A/AQ+a2XV72R8jbHLbaOk1mkvjEeB54CbCCPxzC3KYWyXNIhyFetfM1kGYfo5hDHtQuq6zUwuZM2cODz/8MJ06dSIvL3yFbrvtNt577z0mTZoEwL/9279x2WWXAXDooYcycuRIunfvjiTOPPNMBgwYkLJ+x3Eql2x0vCX5CvhS0olmNhu4GHi9jHuSeRV4TtId0bE1Aw4xsw9TlK9HiEL0OGFd9g0z2xR3L//IzKYr6PTlmtliYDNwSOJmSa2tWBv6HCARqfw54G5JDQhrzT2BOyQdDNQzs80x3Z8wne7UEXr37p1YUtiDESNGlJo/ePBgBg8eXJXdchwnBdk41VwalwDjJC0h7E4ut2OyEEf3euCleP/LpJkmBrYCPeKxplOS2roIGCppMbCc4FQhOOhRkhbGDVhjJS2LbfUnrD1jZiuBFwjr1W8TVLmWAd8C3oj1vg381cxeKO/zOTWbtWvX0rdvX9q3b0+HDh2YOHEiAIsXL+aEE06gU6dO/PCHP2TTpk0AvP322+Tl5ZGXl0fnzp2ZMWNGdXbfcbKT8iwE+yu7Xr65Kj01aePHv/71L5s/f76ZmW3atMlat25ty5cvt27dull+fr6Zmf3xj3+066+/3szMtm7daoWFhUX3Nm/evOi6sqhJ9qmpuI3SU1vtQ23cXCXp+Xgetarq/1tV1Z3URpWIdJTSTpm2knSLpB/E9C8kHVTV/XIyS0XFMw466CAaNAgrTNu2bfPoQ45TDdQox2tmZ5rZxiqs//tVVXdJJM0tRcmqU2XVXx5bmdmNZvZKvPwF4ZyyU0cpTTwD2E08A2Du3Ll06NCBTp06MXny5CJH7DhOZsjo/zhJo4BvLITTuwPobGanxHi2Q4FehKDujQiRgt4gSejCzApS1JtP+YQutphZI0l9gDEUBxGYDww2M5O0BuhmZp9J6gbcbmZ9JJ0MTIxNGnCSmW1O9axm1lPSAcAf4jPtAA6P/egATCVsgqpHEMZ4ryJCHIl+prNVQvUK+HZ8zZT0mZn1TdVvcOWqsqgpylXJqlVbtmxh0KBBTJgwgcaNGzNlyhSGDx/Of//3f3P22Wez3377FZXt2bMny5cvZ+XKlVxyySWcccYZHiDBcTJIpn/qzgauBu4kOI39JTUkOMxZBMeboDXwYzP7qaQngUGEc6+p2G5m3SSNIOzw7Qp8Afwj7jj+vET544AOBFGMObHtN9LUfw1wlZnNiedut5Xjea8CzMw6SWpL2IB1LHAlMNHMHpG0H0FNqx1wAdDLzAol3UPYcFWekINpbRV/6IwkjWxksnJV8+bNefL0g8vRbHayZcsWptUA+ySUfXbs2MF1111Hz549adasWVH+r371KyBswDriiCNKVQLasWMHDz74IG3atKm0ftV51aFKwG2Unrpun0w73vlAV0mNCWdiFxAc8ImEkV7yWdjVtrvQRU4Zde8hdAEgKSF0UdLxvm1mH8Uyi2L96RzvHOD3MU7uM4l7y6A3cBeAmf1d0ofAscCbwK8ltYx1vScpWYgD4ECgvLKPFbXVHpjZfYRYwLRp08b69OlT0Sqyhvz8fGqKfcyMSy65hF69ejFhwoSi/E8//ZQjjjiCXbt2cemllzJq1Cj69OnD6tWrOeqoo2jQoAEffvghn3zyCYMGDeLwww+vtD7VJPvUVNxG6anr9smo440judXApcDfCEdf+gLfA1aWKF5S6OLAMqovS+giVflE/YkyOyhe+y6afzOzsZL+CpwJzJF0mpn9nb3AzB6VNJegMvW8pCvYNyGOitrKqSNUVDzjjTfeYOzYsTRs2JB69epxzz33VKrTdRynbKpjV8VswrTtvxNGp78H5sf11Wrozh6sIYw8/48wZQuApFZmthRYKqk70JZi8YpUzCZMF78Wp5i/A6ySdAzwQZwC/g6QC7xExYQ4KkpCiKNcEYqc2kFFxTMuvvhiLr744qruluM4aaiOXc2zCQITb5rZesJa6exq6EcqbgYmxri1yRubfpEkXFFIcMxlcQ9QT9JSgj7zpRZ0ns8HlsUp7o7AQ1ZxIY6Kch/wgqSZlVin4ziOU0GU6teyk720adPGVq1aVd3dqLFkev1p7dq1DBkyhPXr1yOJyy+/nBEjRnDBBReQ+HfauHEjTZs2ZdGiRaxZs4Z27doVbZg6/vjjmTx5csb6W9fX5yoDt1F6aqt9JM03s25llfMDfI5Tw2nQoAHjx4+nS5cubN68ma5du9KvXz+eeOKJojJXX301TZo0Kbpu1aoVixYtKq06x3GqmWoT0NgblSpJk0oRpbgsRdkqVamS1EnSCkkFSX2ZWwXtzI0BFLZJ2ixpVdxZvbf1rZHku2lqEanUqRKYGU8++SQ//vGPq6uLjuNUgGob8ZrZmXtxz1UVKFulKlVmtlTSmcBfrOLh/CrSTk9JLwAXm1m6406VhgtopCeTAhrJIhmwuzpVgtmzZ/Otb32L1q1bF+WtXr2a4447jsaNG/Ob3/yGE088MSP9dRynbKpsjTcbVKok5RAcb8dSVKpGmtnMfVWpknQjcG20y5+BvwLXmNlZksYQdkofE98nmNmd8b5nCeeXDyCIddwX84ueuUQ7RQIahx/evOuNE+4vzfwO8K0DYX2p387Kp9ORxdPHBQUFjBgxgsGDBxfpMAPccccdHHnkkZx//vkAbN++nYKCApo0acKqVau44YYbmDp1KgcfnBnRjy1bttCoUaOMtFVbcRulp7bap2/fvuVa462yCDfA8cD0mJ5NCEnXkBC0/QrCsZ3DCWIPO4C8WPZJgmNMVW8+8NuYHkFQnmoB7E8IBn9Y/GxLfO9DiLnbkuD43gR6x8/WAIfHdDcgP6b/l6AgBeGHQYMUfckBlsX01cCUmG4L/JPg9O4CLor5+xHO2LaLbTSM+fcAQ8p45m5Jz/OXmB5DOA+9f7Tl50l1NovvBwLLkuxS9MypXh6dKD3VETll+/bt1r9/fxs/fvxu+YWFhXbEEUfY2rVrU9578skn27x586q6i0XU1sgymcRtlJ7aah9qQHSikipVb1KsUlXy+NBq20eVKgvHdBIqVSV528w+MrNdQEKlKh0JlarhQFMz21FGeQgqVX+CoFIFJKtU/UrSaOBoCyP5ZJWqRfH6mHK0URp/NbNvLIxgPyXE3wUYHmPwvkWwSetUFTg1GzNj6NChtGvXjpEjR+722SuvvELbtm1p2bJlUd6GDRvYuTNMnnzwwQe89957HHPM3n69HMepbKrM8ZpZIZCsUjWb8qtUlbX2XOUqVcAwwmhxTtRZ3ivM7FHgbKCAoFJ1CsUqVXnx1cbMxuxlE3s8W5xe/wFwgpl1JkzNuwp+LSWhTvXaa68VBbF//vnnAXj88cf32FQ1a9YscnNzycvL47zzzmPy5Mk0a9asOrruOE4pVPXmKlepqh6VqibAl2b2dfzRcHwl1etUA+nUqaZNm7ZH3qBBgxg0aNCehR3HqRFU9XEiV6mqHpWqFwgj35XAWMJ0c0bYtm0bPXr0oHPnznTo0IGbbroJgBNPPLFotPbtb3+bc889N1NdchzHqVG4cpWzB/uiXGVmbN26lUaNGlFYWEjv3r2ZOHEixx9fPOgeNGgQ55xzDkOGDKmsLmeU2qqqkyncPmXjNkpPbbVPeZWrqk1AI5uQNEbSNaXk50haVsVtb6nK+ktpr+gYQGFhIYWFhSQvK2zatInXXnvNR7yO42QtNVYyUtIkwlnfZCaa2dRq6Esn4OES2d+YWc/Syu9DO3MJR4OSuTiuN2eMvRXQSIg97Ny5k65du/L+++9z1VVX7Sb28Oyzz3LqqafSuHHjSuuv4zhObcKnmisBSSMJG8gAHjCzCZJ+DVxCOOKzlrCp7HZJXYEpsexLwBkWBDhKFdoopa1bgC/MbEK8vjW28SRhbbkx4QfVf5jZ7DjivR/oD3wCXGhmG0qpd58FNJLFHiAcgr/hhhsYPnw43/3udwEYPXo0Z555JieffHKF668p1NbD/ZnC7VM2bqP01Fb7VLuARra8CLuilxJUtBoBy5PyDiI4wvcJalMASwhKWADjKBbg2ENoI0V7OcCCmK4H/AM4jCDg8euYX5+wSxqC8lai3huBu8t6psoU0Lj55ptt3LhxZma2YcMGa9asmRUUFFRa/dVBbT3cnyncPmXjNkpPbbUPNUBAI1voDcwws61mtgV4BhgQ8742s01EwY8YFKKpmc2K9yZPX5cmtLEHZrYG+FzScYRR7EIz+xyYB1wWZSQ7WbHE5S7CSBiCwEfvynjoVGzYsIGNGzcCQeLw5Zdfpm3bcAz6qaee4qyzzuKAA/xIseM42Ys73hqClS60kYoHCMIklxGnraMzP4mg6TxNUqotw1W6tvDxxx/Tt29fcnNz6d69O/369eOss84CShd7cBzHyTZq7OaqWsRsgqMbS1CkGkhY250q6X8INv4hcK+ZbZS0UVJvC5GGLkpUkkJo47UUbc4AbiFoX/8k3n808JGZ3S9pf6AL8BDhx9V5wOOxbJVGOMrNzWXhwoWlfpafn1+VTTuO49QK3PHuI2a2QNI0QhAICJur5kt6AlhM2Pg0L+mWy4ApkoywuSrB+cDFkgoJm6BuS9PmdkkzgY1WHNGoDzAq3r+FELUJYCvQQ9L1sS8X7PXDOo7jOPuMO95KwMx+T5DDTM67Fbi1lLLzgc5JWdfG/LEElakykVSPIAP5o6R6HwQeLKW9KtsauHbtWoYMGcL69euRxOWXX86IESMYM2YM999/P82bNwfgtttu48wzKxx+2XEcp07ijreWIak98BfC5q09jhtlkgYNGjB+/Hi6dOnC5s2b6dq1K/369QPgl7/8Jddcs4dmiOM4TtbjjjcNcYfwFjO7vUR+DiEmbscK1FWheyQdRogqtIkQRQlCeL+PCVPJR0tqFHdSI+l8QnxeAxabWWLtdyfhaBPAP83s7PL2uSxatGhBixZBYvqQQw6hXbt2rFu3rrKqdxzHqZO4462hmNnnkj4gnP99B0BS43g8CUm/B34GjJXUGrgO6GVmX0o6IqmqAjPLq0jb5VGuSqhUFV2vWcPChQvp2bMnc+bM4e677+ahhx6iW7dujB8/nkMPPbQiXXAcx6mzZLVyVYYVp3IIUYPmE3YcLweGWAjd15WwRtwI+IxwVKgXMI1wPKiAEFu3INYlQjSkNWb2W0m/A941swdKaXdLedZ5K6pclaxSVVBQwIgRIxg8eDAnnXQSX3zxBU2aNEESU6ZM4fPPP2f06NFldaHWUFtVdTKF26ds3Ebpqa32ceWqmqk4ZYRRKQQnfg3hSNDfgOYx/wJgSkznA91K1DMVWA/MBA6Kec8CvwPmEEIAnp5UfgfwTsw/tzy2qYhy1fbt261///42fvz4Uj9fvXq1dejQodz11QZqq6pOpnD7lI3bKD211T64clWZZFRxKrLWzObEdEJFqg0hTu/LMWbv9UDLVBWY2WXAt4GVFB8NagC0Jhwp+jFwf+wzsU/dCGd4J0hqlc4oFcHMGDp0KO3atWPkyJFF+R9//HFResaMGXTsWO6lcMdxnDqPr/HuI2b2aIwqNICgOHWFmaUSvig5r28E0Y3lZnZCBdrcKelxwlGkqcBHwFwzKwRWS3qX4Ijnmdm6qQs5bgAACxpJREFUeM8HkvKB4wj6zvvMnDlzePjhh+nUqRN5eWEZ+bbbbuOxxx5j0aJFSCInJ4d77723MppzHMepE2Sz460OxanvSDrBzN6kWEVqFdA8kS+pIXCsmS0HNgOHxHYEtDKz92P6bODvsd5nCSPdqZIOB44FPpB0KPC1mX0T83sRpqQrhd69eyems3fDz+w6juOkJmunms1sAWHz0tvAXKLiFCGgwGLg/9hTcWpSnA5WUv75wLKY35Eg05iKVcBVklYChwJ/MLPtBEnH30paDCwCvh/LTwMmx7oPAh6UtJSwDt2CIBsJ8CIhcMIKwtrvKAuBE9oB78R6ZwJjzWxF+a2UmrVr19K3b1/at29Phw4dmDhxIgDTp0+nQ4cO1KtXj3feeacymnIcx6lTZPOIN6OKUxaiCrVN8dkiQoCDkvlPA08nZfVKcb8BI+MrOf9vQKey+rY3pBLP6NixI8888wxXXHFFVTTrOI5T68naEW91I2mMpD2knSTlSFpWwboqfM++0qJFC7p06QLsLp7Rrl072rRpk8muOI7j1CqyesRbFUTFqVdL+ejUOP1b4ylLQCOdeIbjOI6THne8lUx0rnmliHN8Xpo4B0Ap4hzE/HKJc0TqS7qfsD68DjjHzAokdQf+COwCXiYKf5S8uYSABjd22lGySBHJ4f0S4hnDhg1jwYIFRfkbN25k/vz5bNmyJWU9tZUtW7Z4iMM0uH3Kxm2Unjpvn/Ic9vVXrRDn2AHkxesngcExvYygegVhLXpZWf0vr4BGOvGMk08+2ebNm1euemobtfVwf6Zw+5SN2yg9tdU+uIBGtVId4hyrLWzSgjCSzol1H2Lh+BLAo5XydKQWz3Acx3HS4463BmNmjxLO6xYQxDlOSVP8m6T0Tqp4GSEhnvHaa6+Rl5dHXl4ezz//PDNmzKBly5a8+eabDBgwgNNOO60qu+E4jlPr8DXeqqE6xDn2INa9WVJPM5sLXFhZD5hKPANg4MCBldWM4zhOncMdbxVgZgskTSOIc0AU55CUEOf4lD3FOaZIMpI2VxHEOS6WVAh8Aty2F90ZStBu3gW8Dny1F3U4juM4lYQ73irCMi/O0THp+vakj5ebWS6ApP8iRCpyHMdxqgl3vHWfAZKuI/xbf0iI9es4juNUE+54axF7I85hZk8Q9Kcdx3GcGoA73lpEdK551d0Px3EcZ+9Rqp2pTvYiaTMhkpJTOocDn1V3J2owbp+ycRulp7ba52gza15WIR/xOqWxysy6VXcnaiqS3nH7pMbtUzZuo/TUdfu4gIbjOI7jZBB3vI7jOI6TQdzxOqVxX3V3oIbj9kmP26ds3EbpqdP28c1VjuM4jpNBfMTrOI7jOBnEHa/jOI7jZBB3vM5uSDpd0ipJ70dt56xD0lGSZkpaIWm5pBExv5mklyW9F98PjfmSdGe02RJJXar3CTKDpPqSFkr6S7z+rqS50Q5PSNov5u8fr9+Pn+dUZ78zgaSmkp6S9HdJKyWd4N+fYiT9Mv7fWibpMUkHZNP3xx2vU4Sk+sAk4AygPfBjSe2rt1fVwg7gajNrDxwPXBXt8F/Aq2bWmiDdmfhhcgbQOr4uB/6Q+S5XCyOAlUnXvwXuMLPvAV8SImMR37+M+XfEcnWdicALZtaWEABlJf79AUDSkcBwoJuZdQTqE0KWZs33xx2vk0wP4H0z+8DMtgOPA+dUc58yjpl9bGYLYnoz4Y/mkQRbPBiLPQicG9PnAA9Z4C2gqaQWGe52RpHUEhgAPBCvBZwCPBWLlLRPwm5PAafG8nUSSU2Ak4A/ApjZdjPbiH9/kmkAHCipAXAQ8DFZ9P1xx+skcySwNun6o5iXtcRpreOAucC3zOzj+NEnwLdiOhvtNoEQvnJXvD4M2GhmO+J1sg2K7BM//yqWr6t8F9gATI1T8Q9IOhj//gBgZuuA24F/EhzuV8B8suj7447XcVIgqRHwNPALM9uU/JmFc3hZeRZP0lnApzGOtLMnDYAuwB/M7DhgK8XTykDWf38OJYxivwt8GzgYOL1aO5Vh3PE6yawDjkq6bhnzsg5JDQlO9xEzeyZmr09MAcb3T2N+ttmtF3C2pDWE5YhTCGuaTePUIexugyL7xM+bAKWGsawjfAR8ZGZz4/VTBEfs35/AD4DVZrbBzAqBZwjfqaz5/rjjdZKZB7SOuwv3I2x4+HM19ynjxPWjPwIrzez3SR/9Gbgkpi8BnkvKHxJ3px4PfJU0pVjnMLPrzKylmeUQviOvmdlFwEzgvFispH0Sdjsvlq+zoz0z+wRYK6lNzDoVWIF/fxL8Ezhe0kHx/1rCPlnz/XHlKmc3JJ1JWL+rD0wxs1uruUsZR1JvYDawlOI1zF8R1nmfBL4DfAicb2ZfxD8edxOmy74GLjOzdzLe8WpAUh/gGjM7S9IxhBFwM2AhMNjMvpF0APAwYa38C+BCM/uguvqcCSTlETae7Qd8AFxGGOj49weQdDNwAeEEwUJgGGEtNyu+P+54HcdxHCeD+FSz4ziO42QQd7yO4ziOk0Hc8TqO4zhOBnHH6ziO4zgZxB2v4ziO42QQd7yOk0VI2ilpUdIrZy/qaCrpPyu/d0X1n60MR8aSdG6WBgRxqgE/TuQ4WYSkLWbWaB/ryAH+EiPLVOS++ma2c1/argqiGtIDhGd6qqzyjrOv+IjXcbKcGFd3nKR5MR7sFTG/kaRXJS2QtFRSIlLVWKBVHDGPk9RHMSZvvO9uSZfG9BpJv5W0APiRpFaSXpA0X9JsSW1L6c+lku6O6WmS/iDpLUkfxLamKMS4nZZ0zxZJdyjEeH1VUvOYnxfvXSJphopj4OZLmiDpHWA0cDYwLj5TK0k/jfZYLOlpSQcl9edOSX+L/TkvqQ+jo50WSxob88p8Xif7aFB2Ecdx6hAHSloU06vNbCAh3ulXZtZd0v7AHEkvESLCDDSzTZIOB96S9GeC4H9HM8uDIvWqdHxuZl1i2VeBK83sPUk9gXsIWs/pOBQ4geAc/0zQ9R0GzJOUZ2aLCEL775jZLyXdCNwE/Ax4CPi5mb0u6ZaY/4tY735m1i32qzVJI15JG83s/pj+TbTRXfG+FkBvoG3sz1OSziAI//c0s68lNYtl79uL53XqOO54HSe7KEg4zCT6A7lJo7cmhKDsHwG3STqJIJ15JMWh7CrCE1AU7en7wHQVh1Pdvxz3/6+ZmaSlwHozWxrrWw7kAIti/56I5f8EPKMQF7epmb0e8x8EppfsVwo6RofbFGgEvJj02bNmtgtYISlhjx8AU83sa4AoBbm3z+vUcdzxOo4jwqjwxd0yw3Rxc6CrmRUqRCM6oJT7d7D7slXJMlvjez1CzNWSjr8svonvu5LSietUf8PKs3lla5rPpgHnmtniaIc+pfQHgu1SsbfP69RxfI3XcZwXgf9QCIWIpGMVArc3IcTdLZTUFzg6lt8MHJJ0/4dAe0n7S2pKiDazBzGm8WpJP4rtSFLnSnqGehRHtvkJ8IaZfQV8KenEmH8x8HppN7PnMx0CfBxtclE52n8ZuCxpLbhZFT+vU4txx+s4zgOEsGwLJC0D7iWMJB8BusUp3iHA3wHM7HPCOvAySePMbC0h6s6y+L4wTVsXAUMlLQaWE9ZFK4OtQI/Y/1OAW2L+JYRNU0uAvKT8kjwOjJK0UFIr4AZCNKo5xOdOh5m9QFjvfSeuoV8TP6qq53VqMX6cyHGcWo8q4ZiU42QKH/E6juM4TgbxEa/jOI7jZBAf8TqO4zhOBnHH6ziO4zgZxB2v4ziO42QQd7yO4ziOk0Hc8TqO4zhOBvl/EYqsrj1vHQAAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from lightgbm import plot_importance\r\n",
    "%matplotlib inline\r\n",
    "import matplotlib.pyplot as plt \r\n",
    "plot_importance(lgb_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/featuretools/entityset/entity.py:463: UserWarning: index match_id not found in dataframe, creating new integer column\n",
      "  \"integer column\".format(index))\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Entityset: odds_data\n",
       "  Entities:\n",
       "    data [Rows: 1940, Columns: 7]\n",
       "  Relationships:\n",
       "    No relationships"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import featuretools as ft\r\n",
    "from featuretools.primitives import *\r\n",
    "from featuretools.variable_types import Numeric\r\n",
    "\r\n",
    "data['match_id'] = data.match_time.map(lambda x: str(x)[:10] + '-') + data.home\r\n",
    "\r\n",
    "es = ft.EntitySet(id = 'odds_data')\r\n",
    "\r\n",
    "es = es.entity_from_dataframe(entity_id = 'data', dataframe = data.loc[:,feat_cols], index = 'match_id')\r\n",
    "                            #   variable_types = \r\n",
    "                            #   {\r\n",
    "                            #       'Embarked': ft.variable_types.Categorical,\r\n",
    "                            #       'Sex': ft.variable_types.Boolean,\r\n",
    "                            #       'Title': ft.variable_types.Categorical\r\n",
    "                            #   },\r\n",
    "                            #   )\r\n",
    "\r\n",
    "es\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Entityset: odds_data\n",
       "  Entities:\n",
       "    data [Rows: 1940, Columns: 7]\n",
       "    odds_init_win [Rows: 397, Columns: 1]\n",
       "    odds_init_draw [Rows: 276, Columns: 1]\n",
       "    odds_init_lose [Rows: 587, Columns: 1]\n",
       "    odds_final_win [Rows: 430, Columns: 1]\n",
       "    odds_final_draw [Rows: 304, Columns: 1]\n",
       "    odds_final_lose [Rows: 612, Columns: 1]\n",
       "  Relationships:\n",
       "    data.odds_init_win -> odds_init_win.odds_init_win\n",
       "    data.odds_init_draw -> odds_init_draw.odds_init_draw\n",
       "    data.odds_init_lose -> odds_init_lose.odds_init_lose\n",
       "    data.odds_final_win -> odds_final_win.odds_final_win\n",
       "    data.odds_final_draw -> odds_final_draw.odds_final_draw\n",
       "    data.odds_final_lose -> odds_final_lose.odds_final_lose"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "es = es.normalize_entity(base_entity_id='data', new_entity_id='odds_init_win', index='odds_init_win')\r\n",
    "es = es.normalize_entity(base_entity_id='data', new_entity_id='odds_init_draw', index='odds_init_draw')\r\n",
    "es = es.normalize_entity(base_entity_id='data', new_entity_id='odds_init_lose', index='odds_init_lose')\r\n",
    "es = es.normalize_entity(base_entity_id='data', new_entity_id='odds_final_win', index='odds_final_win')\r\n",
    "es = es.normalize_entity(base_entity_id='data', new_entity_id='odds_final_draw', index='odds_final_draw')\r\n",
    "es = es.normalize_entity(base_entity_id='data', new_entity_id='odds_final_lose', index='odds_final_lose')\r\n",
    "\r\n",
    "es"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<Feature: odds_init_win>,\n",
       " <Feature: odds_init_draw>,\n",
       " <Feature: odds_init_lose>,\n",
       " <Feature: odds_final_win>,\n",
       " <Feature: odds_final_draw>,\n",
       " <Feature: odds_final_lose>,\n",
       " <Feature: odds_init_win.COUNT(data)>,\n",
       " <Feature: odds_init_win.MODE(data.odds_final_draw)>,\n",
       " <Feature: odds_init_win.MODE(data.odds_final_lose)>,\n",
       " <Feature: odds_init_win.MODE(data.odds_final_win)>,\n",
       " <Feature: odds_init_win.MODE(data.odds_init_draw)>,\n",
       " <Feature: odds_init_win.MODE(data.odds_init_lose)>,\n",
       " <Feature: odds_init_win.NUM_UNIQUE(data.odds_final_draw)>,\n",
       " <Feature: odds_init_win.NUM_UNIQUE(data.odds_final_lose)>,\n",
       " <Feature: odds_init_win.NUM_UNIQUE(data.odds_final_win)>,\n",
       " <Feature: odds_init_win.NUM_UNIQUE(data.odds_init_draw)>,\n",
       " <Feature: odds_init_win.NUM_UNIQUE(data.odds_init_lose)>,\n",
       " <Feature: odds_init_draw.COUNT(data)>,\n",
       " <Feature: odds_init_draw.MODE(data.odds_final_draw)>,\n",
       " <Feature: odds_init_draw.MODE(data.odds_final_lose)>,\n",
       " <Feature: odds_init_draw.MODE(data.odds_final_win)>,\n",
       " <Feature: odds_init_draw.MODE(data.odds_init_lose)>,\n",
       " <Feature: odds_init_draw.MODE(data.odds_init_win)>,\n",
       " <Feature: odds_init_draw.NUM_UNIQUE(data.odds_final_draw)>,\n",
       " <Feature: odds_init_draw.NUM_UNIQUE(data.odds_final_lose)>,\n",
       " <Feature: odds_init_draw.NUM_UNIQUE(data.odds_final_win)>,\n",
       " <Feature: odds_init_draw.NUM_UNIQUE(data.odds_init_lose)>,\n",
       " <Feature: odds_init_draw.NUM_UNIQUE(data.odds_init_win)>,\n",
       " <Feature: odds_init_lose.COUNT(data)>,\n",
       " <Feature: odds_init_lose.MODE(data.odds_final_draw)>,\n",
       " <Feature: odds_init_lose.MODE(data.odds_final_lose)>,\n",
       " <Feature: odds_init_lose.MODE(data.odds_final_win)>,\n",
       " <Feature: odds_init_lose.MODE(data.odds_init_draw)>,\n",
       " <Feature: odds_init_lose.MODE(data.odds_init_win)>,\n",
       " <Feature: odds_init_lose.NUM_UNIQUE(data.odds_final_draw)>,\n",
       " <Feature: odds_init_lose.NUM_UNIQUE(data.odds_final_lose)>,\n",
       " <Feature: odds_init_lose.NUM_UNIQUE(data.odds_final_win)>,\n",
       " <Feature: odds_init_lose.NUM_UNIQUE(data.odds_init_draw)>,\n",
       " <Feature: odds_init_lose.NUM_UNIQUE(data.odds_init_win)>,\n",
       " <Feature: odds_final_win.COUNT(data)>,\n",
       " <Feature: odds_final_win.MODE(data.odds_final_draw)>,\n",
       " <Feature: odds_final_win.MODE(data.odds_final_lose)>,\n",
       " <Feature: odds_final_win.MODE(data.odds_init_draw)>,\n",
       " <Feature: odds_final_win.MODE(data.odds_init_lose)>,\n",
       " <Feature: odds_final_win.MODE(data.odds_init_win)>,\n",
       " <Feature: odds_final_win.NUM_UNIQUE(data.odds_final_draw)>,\n",
       " <Feature: odds_final_win.NUM_UNIQUE(data.odds_final_lose)>,\n",
       " <Feature: odds_final_win.NUM_UNIQUE(data.odds_init_draw)>,\n",
       " <Feature: odds_final_win.NUM_UNIQUE(data.odds_init_lose)>,\n",
       " <Feature: odds_final_win.NUM_UNIQUE(data.odds_init_win)>,\n",
       " <Feature: odds_final_draw.COUNT(data)>,\n",
       " <Feature: odds_final_draw.MODE(data.odds_final_lose)>,\n",
       " <Feature: odds_final_draw.MODE(data.odds_final_win)>,\n",
       " <Feature: odds_final_draw.MODE(data.odds_init_draw)>,\n",
       " <Feature: odds_final_draw.MODE(data.odds_init_lose)>,\n",
       " <Feature: odds_final_draw.MODE(data.odds_init_win)>,\n",
       " <Feature: odds_final_draw.NUM_UNIQUE(data.odds_final_lose)>,\n",
       " <Feature: odds_final_draw.NUM_UNIQUE(data.odds_final_win)>,\n",
       " <Feature: odds_final_draw.NUM_UNIQUE(data.odds_init_draw)>,\n",
       " <Feature: odds_final_draw.NUM_UNIQUE(data.odds_init_lose)>,\n",
       " <Feature: odds_final_draw.NUM_UNIQUE(data.odds_init_win)>,\n",
       " <Feature: odds_final_lose.COUNT(data)>,\n",
       " <Feature: odds_final_lose.MODE(data.odds_final_draw)>,\n",
       " <Feature: odds_final_lose.MODE(data.odds_final_win)>,\n",
       " <Feature: odds_final_lose.MODE(data.odds_init_draw)>,\n",
       " <Feature: odds_final_lose.MODE(data.odds_init_lose)>,\n",
       " <Feature: odds_final_lose.MODE(data.odds_init_win)>,\n",
       " <Feature: odds_final_lose.NUM_UNIQUE(data.odds_final_draw)>,\n",
       " <Feature: odds_final_lose.NUM_UNIQUE(data.odds_final_win)>,\n",
       " <Feature: odds_final_lose.NUM_UNIQUE(data.odds_init_draw)>,\n",
       " <Feature: odds_final_lose.NUM_UNIQUE(data.odds_init_lose)>,\n",
       " <Feature: odds_final_lose.NUM_UNIQUE(data.odds_init_win)>]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "features, feature_names = ft.dfs(entityset = es, \r\n",
    "                                 target_entity = 'data', \r\n",
    "                                 max_depth = 2)\r\n",
    "feature_names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>match_id</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>odds_init_win</th>\n",
       "      <td>1.06</td>\n",
       "      <td>1.10</td>\n",
       "      <td>2.18</td>\n",
       "      <td>1.23</td>\n",
       "      <td>2.95</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_init_draw</th>\n",
       "      <td>11.11</td>\n",
       "      <td>9.97</td>\n",
       "      <td>3.31</td>\n",
       "      <td>5.65</td>\n",
       "      <td>2.95</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_init_lose</th>\n",
       "      <td>26.52</td>\n",
       "      <td>21.51</td>\n",
       "      <td>3.07</td>\n",
       "      <td>10.63</td>\n",
       "      <td>2.42</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_final_win</th>\n",
       "      <td>1.07</td>\n",
       "      <td>1.05</td>\n",
       "      <td>2.39</td>\n",
       "      <td>1.19</td>\n",
       "      <td>2.94</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_final_draw</th>\n",
       "      <td>9.80</td>\n",
       "      <td>11.36</td>\n",
       "      <td>2.97</td>\n",
       "      <td>6.27</td>\n",
       "      <td>3.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_final_lose.NUM_UNIQUE(data.odds_final_draw)</th>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>12.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>7.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_final_lose.NUM_UNIQUE(data.odds_final_win)</th>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>13.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>7.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_final_lose.NUM_UNIQUE(data.odds_init_draw)</th>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>14.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>7.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_final_lose.NUM_UNIQUE(data.odds_init_lose)</th>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>12.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>7.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>odds_final_lose.NUM_UNIQUE(data.odds_init_win)</th>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>12.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>7.00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>72 rows × 5 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "match_id                                              0      1      2      3  \\\n",
       "odds_init_win                                      1.06   1.10   2.18   1.23   \n",
       "odds_init_draw                                    11.11   9.97   3.31   5.65   \n",
       "odds_init_lose                                    26.52  21.51   3.07  10.63   \n",
       "odds_final_win                                     1.07   1.05   2.39   1.19   \n",
       "odds_final_draw                                    9.80  11.36   2.97   6.27   \n",
       "...                                                 ...    ...    ...    ...   \n",
       "odds_final_lose.NUM_UNIQUE(data.odds_final_draw)   1.00   1.00  12.00   1.00   \n",
       "odds_final_lose.NUM_UNIQUE(data.odds_final_win)    1.00   1.00  13.00   1.00   \n",
       "odds_final_lose.NUM_UNIQUE(data.odds_init_draw)    1.00   1.00  14.00   1.00   \n",
       "odds_final_lose.NUM_UNIQUE(data.odds_init_lose)    1.00   1.00  12.00   1.00   \n",
       "odds_final_lose.NUM_UNIQUE(data.odds_init_win)     1.00   1.00  12.00   1.00   \n",
       "\n",
       "match_id                                             4  \n",
       "odds_init_win                                     2.95  \n",
       "odds_init_draw                                    2.95  \n",
       "odds_init_lose                                    2.42  \n",
       "odds_final_win                                    2.94  \n",
       "odds_final_draw                                   3.00  \n",
       "...                                                ...  \n",
       "odds_final_lose.NUM_UNIQUE(data.odds_final_draw)  7.00  \n",
       "odds_final_lose.NUM_UNIQUE(data.odds_final_win)   7.00  \n",
       "odds_final_lose.NUM_UNIQUE(data.odds_init_draw)   7.00  \n",
       "odds_final_lose.NUM_UNIQUE(data.odds_init_lose)   7.00  \n",
       "odds_final_lose.NUM_UNIQUE(data.odds_init_win)    7.00  \n",
       "\n",
       "[72 rows x 5 columns]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "features.head().T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from itertools import combinations\r\n",
    "\r\n",
    "def eval():\r\n",
    "    pass\r\n",
    "\r\n",
    "def chose():\r\n",
    "    pass\r\n",
    "\r\n",
    "def rules():\r\n",
    "    pass\r\n",
    "\r\n",
    "for jcd in  jc_data:\r\n",
    "    res = []\r\n",
    "    break\r\n",
    "    for idx in list(combinations(range(14),9)):\r\n",
    "        res.append(jcd.iloc[list(idx)]['result_odds'].product())\r\n",
    "    print(jcd['gid'].max())\r\n",
    "    print(pd.Series(res).describe())\r\n",
    "# idx\r\n",
    "\r\n",
    "def top_N(x,num):\r\n",
    "    x1 = x.min(axis=1)\r\n",
    "    return x1.sort_values(ascending=True).head(num).values\r\n",
    "\r\n",
    "def predict(x):\r\n",
    "    min_odds = min(x['odds_final_win'], x['odds_final_draw'], x['odds_final_lose'])\r\n",
    "    if x['odds_final_win'] == min_odds:\r\n",
    "        return 2\r\n",
    "    elif x['odds_final_draw'] == min_odds:\r\n",
    "        return 1\r\n",
    "    elif x['odds_final_lose'] == min_odds:\r\n",
    "        return 0\r\n",
    "\r\n",
    "def base_algo(x):\r\n",
    "    top = top_N(x.loc[:,['odds_final_win','odds_final_draw','odds_final_lose']],10)\r\n",
    "    # min_odds = \r\n",
    "    x['predict'] = x.apply(predict, axis=1)\r\n",
    "    pred = x.loc[:,['odds_final_win','odds_final_draw','odds_final_lose']].min(axis=1)\r\n",
    "    # print( )# .apply(lambda x:(x['home',x['predict']]), axis=1))\r\n",
    "    # print(x)\r\n",
    "    # x[]\r\n",
    "    return x[pred.isin(top)]\r\n",
    "\r\n",
    "jcd = jc_data[3]\r\n",
    "x = base_algo(jcd)\r\n",
    "sum(x['result_type'] == x['predict'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 10, 2002)"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = list(combinations( x.apply(lambda x: (x['home'], x['predict']), axis=1).tolist(),9))\r\n",
    "a = [sorted(list(aa)) for aa in a]\r\n",
    "b = list(combinations( jcd.apply(lambda x: (x['home'], x['result_type']), axis=1).tolist(),9))\r\n",
    "b = [sorted(list(bb)) for bb in b]\r\n",
    "\r\n",
    "sum([aa in b for aa in a ]), len(a), len(b)\r\n",
    "\r\n",
    "# [1,2] in [[2,1],[1,2]]\r\n",
    "# list(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 查看工作区文件, 该目录下的变更将会持久保存. 请及时清理不必要的文件, 避免加载过慢.\n",
    "# View personal work directory. \n",
    "# All changes under this directory will be kept even after reset. \n",
    "# Please clean unnecessary files in time to speed up environment loading. \n",
    "!ls /home/aistudio/work"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 如果需要进行持久化安装, 需要使用持久化路径, 如下方代码示例:\n",
    "# If a persistence installation is required, \n",
    "# you need to use the persistence path as the following: \n",
    "!mkdir /home/aistudio/external-libraries\n",
    "!pip install beautifulsoup4 -t /home/aistudio/external-libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: \n",
    "# Also add the following code, \n",
    "# so that every time the environment (kernel) starts, \n",
    "# just run the following code: \n",
    "import sys \n",
    "sys.path.append('/home/aistudio/external-libraries')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "请点击[此处](https://ai.baidu.com/docs#/AIStudio_Project_Notebook/a38e5576)查看本环境基本用法.  <br>\n",
    "Please click [here ](https://ai.baidu.com/docs#/AIStudio_Project_Notebook/a38e5576) for more detailed instructions. "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "PaddlePaddle 2.1.2 (Python 3.5)",
   "language": "python",
   "name": "py35-paddle1.2.0"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
